advance java by RohitRathour

VIEWS: 231 PAGES: 328

									                   ADVANCE JAVA
                    SECTION-A
                     CORE JAVA
TOPICS COVERED IN THIS SECTION:-
CORE JAVA

     Introduction to Java,
     Data types,
     variables,
     operators,
     Arrays,
     Control Statements,
     Classes & Methods,
     Inheritance,
     Exception Handling,
     Multithreading,
     Collections,
     I/O streams,
     AVVT & Apolet Programming.
NETWORKING

     Connecting to a Server,
     Implementing Servers,
     Sending E-Mail,
     Making URL Connections,
     Advanced Socket Programm ing
Introduction to Java:-
Java is a simple and yet powerful object oriented programming language and it is in many
respects similar to C++. Java originated at Sun Microsystems, Inc. in 1991. It was conceived
by James Gosling, Patrick Naughton, Chris Warth, Ed Frank, and Mike Sheridan at Sun
Microsystems, Inc. It was developed to provide a platform-independent programming
language. This site gives you an Introduction to Java Programming accompanied with
many java examples. Its a complete course in java programming for beginners to advanced
java.

Platform independent
Unlike many other programming languages including C and C++ when Java is compiled, it is
not compiled into platform specific machine, rather into platform independent byte code. This
byte code is distributed over the web and interpreted by v CORE JAVA Introduction to
Java, Data types, variables, operators, Arrays, Control Statements, Classes & Methods,
Inheritance, Exception Handling, Multithreading, Collections, I/O streams, AVVT & Apolet
Programming. NETWORKING Connecting to a Server, Implementing Servers, Sending E-
Mail, Making URL Connections, Advanced Socket Programm ing irtual Machine (JVM) on
whichever platform it is being run.

Java Virtual Machine
What is the Java Virtual Machine? What is its role?

Java was designed with a concept of ‘write once and run everywhere’. Java Virtual Machine
plays the central role in this concept. The JVM is the environment in which Java programs
execute. It is a software that is implemented on top of real hardware and operating system.
When the source code (.java files) is compiled, it is translated into byte codes and then placed
into (.class) files. The JVM executes these bytecodes. So Java byte codes can be thought of as
the machine language of the JVM. A JVM can either interpret the bytecode one instruction at
a time or the bytecode can be compiled further for the real microprocessor using what is
called a just-in-time compiler. The JVM must be implemented on a particular platform before
compiled programs can run on that platform.

Object Oriented Programming
Since Java is an object oriented programming language it has following features:

      Reusability of Code
      Emphasis on data rather than procedure
      Data is hidden and cannot be accessed by external functions
      Objects can communicate with each other through functions
      New data and functions can be easily addedJava has powerful features. The following are
       some of them:-

       Simple
       Reusable
       Portable (Platform Independent)
       Distributed
       Robust
       Secure
       High Performance
       Dynamic
       Threaded
       Interpreted

Object Oriented Programming is a method of implementation in which programs are
organized as cooperative collection of objects, each of which represents an instance of a
class, and whose classes are all members of a hierarchy of classes united via inheritance
relationships.

OOP Concepts

Four principles of Object Oriented Programming are
Abstraction
Encapsulation
Inheritance
Polymorphism

Abstraction

Abstraction denotes the essential characteristics of an object that distinguish it from all other
kinds of objects and thus provide crisply defined conceptual boundaries, relative to the
perspective of the viewer.

Encapsulation

Encapsulation is the process of compartmentalizing the elements of an abstraction that
constitute its structure and behavior ; encapsulation serves to separate the contractual
interface of an abstraction and its implementation.

Encapsulation

* Hides the implementation details of a class.
* Forces the user to use an interface to access data
* Makes the code more maintainable.

Inheritance

Inheritance is the process by which one object acquires the properties of another object.

Polymorphism
Polymorphism is the existence of the classes or methods in different forms or single name
denoting different
implementations.

Java is Distributed
With extensive set of routines to handle TCP/IP protocols like HTTP and FTP java can open
and access the objects across net via URLs.

Java is Multithreaded
One of the powerful aspects of the Java language is that it allows multiple threads of
execution to run concurrently within the same program A single Java program can have many
different threads executing independently and continuously. Multiple Java applets can run on
the browser at the same time sharing the CPU time.

Java is Secure
Java was designed to allow secure execution of code across network. To make Java secure
many of the features of C and C++ were eliminated. Java does not use Pointers. Java
programs cannot access arbitrary addresses in memory.

Garbage collection
Automatic garbage collection is another great feature of Java with which it prevents
inadvertent corruption of memory. Similar to C++, Java has a new operator to allocate
memory on the heap for a new object. But it does not use delete operator to free the memory
as it is done in C++ to free the memory if the object is no longer needed. It is done
automatically with garbage collector.

Java Applications
Java has evolved from a simple language providing interactive dynamic content for web
pages to a predominant enterprise-enabled programming language suitable for developing
significant and critical applications. Today, It is used for many types of applications
including Web based applications, Financial applications, Gaming applications, embedded
systems, Distributed enterprise applications, mobile applications, Image processors, desktop
applications and many more. This site outlines the building blocks of java by stating few java
examples along with some java tutorials.

Java Architecture


The Java environment is composed of a number of system components. You use these
components at compile time to create the Java program and at run time to execute the
program. Java achieves its independence by creating programs designed to run on the Java
Virtual Machine rather than any specific computer system.

      After you write a Java program, you use a compiler that reads the statements in the program
       and translates them into a machine independent format called bytecode.
      Bytecode files, which are very compact, are easily transported through a distributed system
       like the Internet.
      The compiled Java code (resulting byte code) will be executed at run time.

Java programs can be written and executed in two ways:

      Stand-alone application (A Java Swing Application)
      Applet which runs on a web browser (Example: Internet Explorer)




Java source code
A Java program is a collection of one or more java classes. A Java source file can contain
more than one class definition and has a .java extension. Each class definition in a source file
is compiled into a separate class file. The name of this compiled file is comprised of the name
of the class with .class as an extension. Before we proceed further in this section, I would
recommend you to go through the ‘Basic Language Elements’.

Below is a java sample code for the traditional Hello World program. Basically, the idea
behind this Hello World program is to learn how to create a program, compile and run it. To
create your java source code you can use any editor( Text pad/Edit plus are my favorites) or
you can use an IDE like Eclipse.

public class HelloWorld {
        public static void main(String[] args) {
                System.out.println("Hello World");
        }//End of main
}//End of HelloWorld Class



Output
Hello World

ABOUT THE PROGRAM

I created a class named “HelloWorld” containing a simple main function within it. The
keyword class specifies that we are defining a class. The name of a public class is spelled
exactly as the name of the file (Case Sensitive). All java programs begin execution with the
method named main(). main method that gets executed has the following signature : public
static void main(String args[]).Declaring this method as public means that it is accessible
from outside the class so that the JVM can find it when it looks for the program to start it. It
is necessary that the method is declared with return type void (i.e. no arguments are returned
from the method). The main method contains a String argument array that can contain the
command line arguments. The brackets { and } mark the beginning and ending of the class.
The program contains a line ‘System.out.println(“Hello World”);’ that tells the computer to
print out on one line of text namely ‘Hello World’. The semi-colon ‘;’ ends the line of code.
The double slashes ‘//’ are used for comments that can be used to describe what a source code
is doing. Everything to the right of the slashes on the same line does not get compiled, as they
are simply the comments in a program.

Java Main method Declarations

class MainExample1 {public static void main(String[] args) {}}
class MainExample2 {public static void main(String []args) {}}
class MainExample3 {public static void main(String args[]) {}}

All the 3 valid main method’s shown above accepts a single String array argument.

Compiling and Running an Application
To compile and run the program you need the JDK distributed by Sun Microsystems. The
JDK contains documentation, examples, installation instructions, class libraries and packages,
and tools. Download an editor like Textpad/EditPlus to type your code. You must save your
source code with a .java extension. The name of the file must be the name of the public class
contained in the file.

Steps for Saving, compiling and Running a Java

Step 1:Save the program With .java Extension.
Step 2:Compile the file from DOS prompt by typing javac <filename>.
Step 3:Successful Compilation, results in creation of .class containing byte code
Step 4:Execute the file by typing java <filename without extension>

Java Development Kit
The Java Developer’s Kit is distributed by Sun Microsystems. The JDK contains
documentation, examples, installation instructions, class libraries and packages, and tools

javadoc
The javadoc tool provided by Sun is used to produce documentation for an application or
program,

Jar Files
A jar file is used to group together related class files into a single file for more compact
storage, distribution, and transmission.

PATH and CLASSPATH
The following are the general programming errors, which I think every beginning java
programmer would come across. Here is a solution on how to solve the problems when
running on a Microsoft Windows Machine.

1. ‘javac’ is not recognized as an internal or external command, operable program or
batch file

When you get this error, you should conclude that your operating system cannot find the
compiler (javac). To solve this error you need to set the PATH variable.

How to set the PATH Variable?

Firstly the PATH variable is set so that we can compile and execute programs from any
directory without having to type the full path of the command. To set the PATH of jdk on
your system (Windows XP), add the full path of the jdk<version>\bin directory to the PATH
variable. Set the PATH as follows on a Windows machine:

a. Click Start > Right Click “My Computer” and click on “Properties”
b. Click Advanced > Environment Variables.
c. Add the location of bin folder of JDK installation for PATH in User Variables and System
Variables. A typical value for PATH is:

C:\jdk<version>\bin (jdk<version is nothing but the name of the directory where jdk is
installed)

If there are already some entries in the PATH variable then you must add a semicolon and
then add the above value (Version being replaced with the version of JDK). The new path
takes effect in each new command prompt window you open after setting the PATH variable.

2. Exception in thread “main” java.lang.NoClassDefFoundError: HelloWorld

If you receive this error, java cannot find your compiled byte code file, HelloWorld.class.If
both your class files and source code are in the same working directory and if you try running
your program from the current working directory than, your program must get executed
without any problems as, java tries to find your .class file is your current directory. If your
class files are present in some other directory other than that of the java files we must set the
CLASSPATH pointing to the directory that contain your compiled class files.CLASSPATH
can be set as follows on a Windows machine:

a. Click Start > Right Click “My Computer” and click on “Properties”
b. Click Advanced > Environment Variables.

Add the location of classes’ folder containing all your java classes in User Variables.

If there are already some entries in the CLASSPATH variable then you must add a semicolon
and then add the new value . The new class path takes effect in each new command prompt
window you open after setting the CLASSPATH variable.
Java 1.5
The Java 1.5 released in September 2004.

Goals

Less code complexity
Better readability
More compile-time type safety
Some new functionality (generics, scanner)

New Features

Enhanced for loop
Enumerated types
Autoboxing & unboxing
Generic types
Scanner
Variable number of arguments (varargs)
Static imports
Annotations

This part of the java tutorial teaches you the basic language elements and syntax for the java
programming language. Once you get these basic language concepts you can continue with
the other object oriented programming language concepts.


Keywords
There are certain words with a specific meaning in java which tell (help) the compiler what
the program is supposed to do. These Keywords cannot be used as variable names, class
names, or method names. Keywords in java are case sensitive, all characters being lower
case.




Keywords are reserved words that are predefined in the language; see the table below (Taken
from Sun Java Site). All the keywords are in lowercase.

         abstract          default           if                  private            this
         boolean           do                implements          protected          throw
         break             double            import              public             throws
         byte              else              instanceof          return             transient
         case              extends           int                 short              try
         catch             final             interface           static             void
         char              finally           long                strictfp           volatile
         class             float             native              super              while
         const             for               new                 switch
         continue          goto             package               synchronized

Keywords are marked in yellow as shown in the sample code below

/** This class is a Hello World Program used to introduce
the Java Language*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println(“Hello World”); //Prints output to console

}
}

For more information on different Keywords – Java Keywords

Some Tricky Observations: The words virtual, ifdef, typedef, friend, struct and union are all
words related to

the C programming language. const and goto are Java keywords. The word finalize is the
name of a method

of the Object class and hence not a keyword. enum and label are not keywords.


Comments
Comments are descriptions that are added to a program to make code easier to understand.
The compiler ignores comments and hence its only for documentation of the program.

Java supports three comment styles.

Block style comments begin with /* and terminate with */ that spans multiple lines.

Line style comments begin with // and terminate at the end of the line. (Shown in the above
program)

Documentation style comments begin with /** and terminate with */ that spans multiple lines.
They are generally created using the automatic documentation generation tool, such as
javadoc. (Shown in the above program)

name of this compiled file is comprised of the name of the class with .class as an extension.

Data types and variables:-

Variable, Identifiers and Data Types
Variables are used for data that change during program execution. All variables have a name,
a type, and a scope. The programmer assigns the names to variables, known as identifiers.
An Identifier must be unique within a scope of the Java program. Variables have a data type,
that indicates the kind of value they can store. Variables declared inside of a block or method
are called local variables; They are not automatically initialized. The compiler will generate
an error as a result of the attempt to access the local variables before a value has been
assigned.

public class localVariableEx {
   public static int a;
   public static void main(String[] args) {
     int b;
     System.out.println("a : "+a);
     System.out.println("b : "+b);     //Compilation error
}}

Note in the above example, a compilation error results in where the variable is tried to be
accessed and not at the place where its declared without any value.

The data type indicates the attributes of the variable, such as the range of values that can be
stored and the operators that can be used to manipulate the variable. Java has four main
primitive data types built into the language. You can also create your own composite data
types.

Java has four main primitive data types built into the language. We can also create our own
data types.

 Integer: byte, short, int, and long.

 Floating Point: float and double

 Character: char

 Boolean: variable with a value of true or false.

The following chart (Taken from Sun Java Site) summarizes the default values for the java
built in data types. Since I thought Mentioning the size was not important as part of learning
Java, I have not mentioned it in the below table. The size for each Java type can be obtained
by a simple Google search.

        Data Type                    Default Value (for fields)               Range

           Byte                                  0                         -127 to +128

           Short                                 0                      -32768 to +32767

            Int                                  0

           Long                                 0L

           Float                                0.0f
          Double                              0.0d

            Char                            ‘\u0000′                            0 to 65535

       String (object)                         null

          Boolean                             false


When we declare a variable we assign it an identifier and a data type.

For Example

String message = “hello world”

In the above statement, String is the data type for the identifier message. If you don’t
specify a value when the variable is declared, it will be assigned the default value for its data
type.

Identifier Naming Rules

        Can consist of upper and lower case letters, digits, dollar sign ($) and the underscore ( _ )
         character.
        Must begin with a letter, dollar sign, or an underscore
        Are case sensitive
        Keywords cannot be used as identifiers
        Within a given section of your program or scope, each user defined item must have a unique
         identifier
        Can be of any length.


Operators:-
Java provides a rich set of operators to manipulate variables. We can divide all the Java
operators into the following groups:

        Arithmetic Operators
        Relational Operators
        Bitwise Operators
        Logical Operators
        Assignment Operators
        Misc Operators
The Arithmetic Operators:
Arithmetic operators are used in mathematical expressions in the same way that they are used
in algebra. The following table lists the arithmetic operators:

Assume integer variable A holds 10 and variable B holds 20 then:

Show Examples

Operator                 Description                                  Example
            Addition - Adds values on either side
+                                                     A + B will give 30
            of the operator
            Subtraction - Subtracts right hand
-                                                     A - B will give -10
            operand from left hand operand
            Multiplication - Multiplies values on
*                                                     A * B will give 200
            either side of the operator
            Division - Divides left hand operand
/                                                     B / A will give 2
            by right hand operand
            Modulus - Divides left hand operand
%           by right hand operand and returns         B % A will give 0
            remainder
            Increment - Increase the value of
++                                                    B++ gives 21
            operand by 1
            Decrement - Decrease the value of
--                                                    B-- gives 19
            operand by 1


The Relational Operators:
There are following relational operators supported by Java language

Assume variable A holds 10 and variable B holds 20 then:

Show Examples

Operator                 Description                                  Example
            Checks if the value of two operands
==          are equal or not, if yes then condition   (A == B) is not true.
            becomes true.
            Checks if the value of two operands
!=                                                    (A != B) is true.
            are equal or not, if values are not equal
               then condition becomes true.
               Checks if the value of left operand is
 >             greater than the value of right operand, (A > B) is not true.
               if yes then condition becomes true.
               Checks if the value of left operand is
 <             less than the value of right operand, if   (A < B) is true.
               yes then condition becomes true.
               Checks if the value of left operand is
               greater than or equal to the value of
 >=                                                       (A >= B) is not true.
               right operand, if yes then condition
               becomes true.
               Checks if the value of left operand is
               less than or equal to the value of right
 <=                                                       (A <= B) is true.
               operand, if yes then condition
               becomes true.


The Bitwise Operators:
Java defines several bitwise operators which can be applied to the integer types, long, int,
short, char, and byte.

Bitwise operator works on bits and perform bit by bit operation. Assume if a = 60; and b =
13; Now in binary format they will be as follows:

a = 0011 1100

b = 0000 1101

-----------------

a&b = 0000 1100

a|b = 0011 1101

a^b = 0011 0001

~a = 1100 0011

The following table lists the bitwise operators:

Assume integer variable A holds 60 and variable B holds 13 then:

Show Examples
Operator                   Description                                       Example
             Binary AND Operator copies a bit to         (A & B) will give 12 which is 0000
&
             the result if it exists in both operands.   1100
             Binary OR Operator copies a bit if it       (A | B) will give 61 which is 0011
|
             exists in eather operand.                   1101
             Binary XOR Operator copies the bit if       (A ^ B) will give 49 which is 0011
^
             it is set in one operand but not both.      0001
             Binary Ones Complement Operator is
                                                         (~A ) will give -60 which is 1100
~            unary and has the efect of 'flipping'
                                                         0011
             bits.
             Binary Left Shift Operator. The left
             operands value is moved left by the         A << 2 will give 240 which is 1111
<<
             number of bits specified by the right       0000
             operand.
             Binary Right Shift Operator. The left
             operands value is moved right by the
>>                                                       A >> 2 will give 15 which is 1111
             number of bits specified by the right
             operand.
             Shift right zero fill operator. The left
             operands value is moved right by the
                                                         A >>>2 will give 15 which is 0000
>>>          number of bits specified by the right
                                                         1111
             operand and shifted values are filled
             up with zeros.


The Logical Operators:
The following table lists the logical operators:

Assume boolean variables A holds true and variable B holds false then:

Show Examples

Operator                   Description                                       Example
             Called Logical AND operator. If both
&&           the operands are non zero then then         (A && B) is false.
             condition becomes true.
             Called Logical OR Operator. If any of
||           the two operands are non zero then          (A || B) is true.
             then condition becomes true.
!            Called Logical NOT Operator. Use to         !(A && B) is true.
            reverses the logical state of its
            operand. If a condition is true then
            Logical NOT operator will make false.




The Assignment Operators:
There are following assignment operators supported by Java language:

Show Examples

Operator              Description                                Example
            Simple assignment operator,
                                                C = A + B will assigne value of A + B into
=           Assigns values from right side
                                                C
            operands to left side operand
            Add AND assignment operator, It
            adds right operand to the left
+=                                           C += A is equivalent to C = C + A
            operand and assign the result to
            left operand
            Subtract AND assignment
            operator, It subtracts right
-=                                            C -= A is equivalent to C = C - A
            operand from the left operand and
            assign the result to left operand
            Multiply AND assignment
            operator, It multiplies right
*=                                              C *= A is equivalent to C = C * A
            operand with the left operand and
            assign the result to left operand
            Divide AND assignment operator,
            It divides left operand with the
/=                                              C /= A is equivalent to C = C / A
            right operand and assign the result
            to left operand
            Modulus AND assignment
            operator, It takes modulus using
%=                                             C %= A is equivalent to C = C % A
            two operands and assign the result
            to left operand
            Left shift AND assignment
<<=                                             C <<= 2 is same as C = C << 2
            operator
            Right shift AND assignment
>>=                                             C >>= 2 is same as C = C >> 2
            operator
             Bitwise AND assignment
 &=                                                C &= 2 is same as C = C & 2
             operator
             bitwise exclusive OR and
 ^=                                                C ^= 2 is same as C = C ^ 2
             assignment operator
             bitwise inclusive OR and
 |=                                                C |= 2 is same as C = C | 2
             assignment operator




Misc Operators
There are few other operators supported by Java Language.

Conditional Operator ( ? : ):
Conditional operator is also known as the ternary operator. This operator consists of three
operands and is used to evaluate boolean expressions. The goal of the operator is to decide
which value should be assigned to the variable. The operator is written as :

 variable x = (expression) ? value if true : value if false


Following is the example:

 public class Test {
    public static void main(String args[]){
       int a , b;
       a = 10;
       b = (a == 1) ? 20: 30;
       System.out.println( "Value of b is : " +                 b );

          b = (a == 10) ? 20: 30;
          System.out.println( "Value of b is : " + b );
      }
 }


This would produce following result:

 Value of b is : 30
 Value of b is : 20


instanceOf Operator:
This operator is used only for object reference variables. The operator checks whether the
object is of a particular type(class type or interface type). instanceOf operator is wriiten as:
 ( Object reference variable ) instanceOf               (class/interface type)


If the object referred by the variable on the left side of the operator passes the IS-A check for
the class/interface type on the right side then the result will be true. Following is the example:

 String name = = 'James';
 boolean result = name instanceOf String;
 // This will return true since name is type of String


This operator will still return true if the object being compared is the assignment compatible
with the type on the right. Following is one more example:

 class Vehicle {}

 public class Car extends Vehicle {
    public static void main(String args[]){
       Vehicle a = new Car();
       boolean result = a instanceof Car;
       System.out.println( result);
    }
 }


This would produce following result:

 true



Precedence of Java Operators:
Operator precedence determines the grouping of terms in an expression. This affects how an
expression is evaluated. Certain operators have higher precedence than others; for example,
the multiplication operator has higher precedence than the addition operator:

For example x = 7 + 3 * 2; Here x is assigned 13, not 20 because operator * has higher
precedenace than + so it first get multiplied with 3*2 and then adds into 7.

Here operators with the highest precedence appear at the top of the table, those with the
lowest appear at the bottom. Within an expression, higher precedenace operators will be
evaluated first.

      Category                               Operator                          Associativity
Postfix                 () [] . (dot operator)                               Left to right
Unary                   ++ - - ! ~                                           Right to left
Multiplicative          */%                                                  Left to right
Additive                +-                                                   Left to right
Shift                   >> >>> <<                                           Left to right
Relational              > >= < <=                                           Left to right
Equality                == !=                                               Left to right
Bitwise AND             &                                                   Left to right
Bitwise XOR             ^                                                   Left to right
Bitwise OR              |                                                   Left to right
Logical AND             &&                                                  Left to right
Logical OR              ||                                                  Left to right
Conditional             ?:                                                  Right to left
Assignment              = += -= *= /= %= >>= <<= &= ^= |=                   Right to left
Comma                   ,                                                   Left to right




                                        Advertisements


                                         Arrays:-

Java provides a data structure, the array, which stores a fixed-size sequential collection of
elements of the same type. An array is used to store a collection of data, but it is often more
useful to think of an array as a collection of variables of the same type.

Instead of declaring individual variables, such as number0, number1, ..., and number99, you
declare one array variable such as numbers and use numbers[0], numbers[1], and ...,
numbers[99] to represent individual variables.

This tutorial introduces how to declare array variables, create arrays, and process arrays using
indexed variables.


Declaring Array Variables:
To use an array in a program, you must declare a variable to reference the array, and you
must specify the type of array the variable can reference. Here is the syntax for declaring an
array variable:

 dataType[] arrayRefVar;            // preferred way.
 or

 dataType arrayRefVar[];         //    works but not preferred way.


Note: The style dataType[] arrayRefVar is preferred. The style dataType arrayRefVar[]
comes from the C/C++ language and was adopted in Java to accommodate C/C++
programmers.

Example:
The following code snippets are examples of this syntax:

 double[] myList;                // preferred way.

 or

 double myList[];                //    works but not preferred way.



Creating Arrays:
You can create an array by using the new operator with the following syntax:

 arrayRefVar = new dataType[arraySize];


The above statement does two things:

      It creates an array using new dataType[arraySize];
      It assigns the reference of the newly created array to the variable arrayRefVar.

Declaring an array variable, creating an array, and assigning the reference of the array to the
variable can be combined in one statement, as shown below:

 dataType[] arrayRefVar = new dataType[arraySize];


Alternatively you can create arrays as follows:

 dataType[] arrayRefVar = {value0, value1, ..., valuek};


The array elements are accessed through the index. Array indices are 0-based; that is, they
start from 0 to arrayRefVar.length-1.

Example:
Following statement declares an array variable, myList, creates an array of 10 elements of
double type, and assigns its reference to myList.:

 double[] myList = new double[10];


Following picture represents array myList. Here myList holds ten double values and the
indices are from 0 to 9.




Processing Arrays:
When processing array elements, we often use either for loop or foreach loop because all of
the elements in an array are of the same type and the size of the array is known.

Example:
Here is a complete example of showing how to create, initialize and process arrays:

 public class TestArray {
    public static void main(String[] args) {
       double[] myList = {1.9, 2.9, 3.4, 3.5};

         // Print all the array elements
         for (int i = 0; i < myList.length; i++) {
            System.out.println(myList[i] + " ");
         }
         // Summing all elements
         double total = 0;
         for (int i = 0; i < myList.length; i++) {
            total += myList[i];
         }
         System.out.println("Total is " + total);
         // Finding the largest element
         double max = myList[0];
         for (int i = 1; i < myList.length; i++) {
            if (myList[i] > max) max = myList[i];
         }
         System.out.println("Max is " + max);
        }
    }


This would produce following result:

    1.9
    2.9
    3.4
    3.5
    Total is 11.7
    Max is 3.5



Passing Arrays to Methods:
Just as you can pass primitive type values to methods, you can also pass arrays to methods.
For example, the following method displays the elements in an int array:

public static void printArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
    System.out.print(array[i] + " ");
  }
}


You can invoke it by passing an array. For example, the following statement invokes the
printArray method to display 3, 1, 2, 6, 4, and 2:

printArray(new int[]{3, 1, 2, 6, 4, 2});



Returning an Array from a Method:
A method may also return an array. For example, the method shown below returns an array
that is the reversal of another array:

public static int[] reverse(int[] list) {
  int[] result = new int[list.length];

    for (int i = 0; i = result.length - 1;
                        i < list.length; i++, j--) {
      result[j] = list[i];
    }
    result result;
}



The Arrays Class:
The java.util.Arrays class contains various static methods for sorting and searching arrays,
comparing arrays, and filling array elements. These methods are overloaded for all primitive
types.

SN                                      Methods with Description


     public static int binarySearch(Object[] a, Object key)
     Searches the specified array of Object ( Byte, Int , double etc) for the specified value using the
1
     binary search algorithm. The array must be sorted prior to making this call. This returns index of
     the search key, if it is contained in the list; otherwise, (-(insertion point + 1).


     public static boolean equals(long[] a, long[] a2)
     Returns true if the two specified arrays of longs are equal to one another. Two arrays are
2    considered equal if both arrays contain the same number of elements, and all corresponding
     pairs of elements in the two arrays are equal. This returns true if the two arrays are equal.
     Same method could be used by all other premitive data types ( Byte, short, Int etc.)


     public static void fill(int[] a, int val)
3    Assigns the specified int value to each element of the specified array of ints. Same method
     could be used by all other premitive data types ( Byte, short, Int etc.)


     public static void sort(Object[] a)
4    Sorts the specified array of objects into ascending order, according to the natural ordering of its
     elements. Same method could be used by all other premitive data types ( Byte, short, Int etc.)




Control Statements:-

Java Control Statements

In this section, we are going to discuss the control statements. Different types of control
statements: the decision making statements (if-then, if-then-else and switch), looping
statements (while, do-while and for) and branching statements (break, continue and return).

Control Statements
The control statement are used to controll the flow of execution of the program . This
execution order depends on the supplied data values and the conditional logic. Java contains
the following types of control statements:
1- Selection Statements
2- Repetition Statements
3- Branching Statements

Selection statements:

   1. If Statement:
      This is a control statement to execute a single statement or a block of code, when the
      given condition is true and if it is false then it skips if block and rest code of program
      is executed .

           Syntax:
           if(conditional_expression){
           <statements>;
           ...;
           ...;
       }

       Example: If n%2 evaluates to 0 then the "if" block is executed. Here it evaluates to 0
       so if block is executed. Hence "This is even number" is printed on the screen.

       int n = 10;

       if(n%2 = = 0){

         System.out.println("This
       is even number");

       }

   2.
   3. If-else Statement:
      The "if-else" statement is an extension of if statement that provides another option
      when 'if' statement evaluates to "false" i.e. else block is executed if "if" statement is
      false.

           Syntax:
            if(conditional_expression){
           <statements>;
           ...;
           ...;
           }
            else{
           <statements>;
           ....;
           ....;
            }

       Example: If n%2 doesn't evaluate to 0 then else block is executed. Here n%2
   evaluates to 1 that is not equal to 0 so else block is executed. So "This is not even
   number" is printed on the screen.

   int n = 11;

   if(n%2 = = 0){

     System.out.println("This is
   even number");

   }

   else{

     System.out.println("This is
   not even number");

   }

4.
5. Switch Statement:
   This is an easier implementation to the if-else statements. The keyword "switch" is
   followed by an expression that should evaluates to byte, short, char or int primitive
   data types ,only. In a switch block there can be one or more labeled cases. The
   expression that creates labels for the case must be unique. The switch expression is
   matched with each case label. Only the matched case is executed ,if no case matches
   then the default statement (if present) is executed.

   Syntax:
    switch(control_expression){
    case expression 1:
    <statement>;
    case expression 2:
    <statement>;
     ...
     ...
    case expression n:
    <statement>;
    default:
    <statement>;
    }//end switch

   Example: Here expression "day" in switch statement evaluates to 5 which matches
   with a case labeled "5" so code in case 5 is executed that results to output "Friday"
   on the screen.

   int day = 5;

   switch (day) {
    case 1:
        System.out.println("Monday");
        break;
         case 2:
         System.out.println("Tuesday");
         break;
        case 3:

      System.out.println("Wednesday");
        break;
        case 4:
        System.out.println("Thrusday");
        break;
        case 5:
         System.out.println("Friday");
         break;
        case 6:
         System.out.println("Saturday");
         break;
        case 7:
        System.out.println("Sunday");
        break;
        default:
         System.out.println("Invalid
      entry");
         break;
      }

Repetition Statements:

   1. while loop statements:
      This is a looping or repeating statement. It executes a block of code or statements till
      the given condition is true. The expression must be evaluated to a boolean value. It
      continues testing the condition and executes the block of code. When the expression
      results to false control comes out of loop.

      Syntax:
        while(expression){
       <statement>;
       ...;
       ...;
       }

      Example: Here expression i<=10 is the condition which is checked before entering
      into the loop statements. When i is greater than value 10 control comes out of loop
      and next statement is executed. So here i contains value "1" which is less than number
      "10" so control goes inside of the loop and prints current value of i and increments
      value of i. Now again control comes back to the loop and condition is checked. This
      procedure continues until i becomes greater than value "10". So this loop prints values
      1 to 10 on the screen.
   int i = 1;

   //print 1 to 10

   while (i <= 10){


   System.out.println("Num
   " + i);

       i++;

   }

2.
3. do-while loop statements:
   This is another looping statement that tests the given condition past so you can say
   that the do-while looping statement is a past-test loop statement. First the do block
   statements are executed then the condition given in while statement is checked. So in
   this case, even the condition is false in the first attempt, do block of code is executed
   at least once.

   Syntax:
    do{
    <statement>;
    ...;
    ...;
    }while (expression);

   Example: Here first do block of code is executed and current value "1" is printed then
   the condition i<=10 is checked. Here "1" is less than number "10" so the control
   comes back to do block. This process continues till value of i becomes greater than
   10.

   int i = 1;

   do{


   System.out.println("Num:
   " + i);

       i++;

   }while(i <= 10);

4.
5. for loop statements:
   This is also a loop statement that provides a compact way to iterate over a range of
   values. From a user point of view, this is reliable because it executes the statements
      within this block repeatedly till the specified conditions is true .

      Syntax:
          for (initialization; condition; increment or decrement){
        <statement>;
        ...;
        ...;
        }
      initialization: The loop is started with the value specified.
      condition: It evaluates to either 'true' or 'false'. If it is false then the loop is
      terminated.
      increment or decrement: After each iteration, value increments or decrements.

      Example: Here num is initialized to value "1", condition is checked whether
      num<=10. If it is so then control goes into the loop and current value of num is
      printed. Now num is incremented and checked again whether num<=10.If it is so then
      again it enters into the loop. This process continues till num>10. It prints values 1
      to10 on the screen.

      for (int num = 1; num <=
      10; num++){


      System.out.println("Num:
      " + num);

      }

Branching Statements:

   1. Break statements:
      The break statement is a branching statement that contains two forms: labeled and
      unlabeled. The break statement is used for breaking the execution of a loop (while,
      do-while and for) . It also terminates the switch statements.

      Syntax:
       break; // breaks the innermost loop or switch statement.
       break label; // breaks the outermost loop in a series of nested loops.

      Example: When if statement evaluates to true it prints "data is found" and comes out
      of the loop and executes the statements just following the loop.
2. Continue statements:
   This is a branching statement that are used in the looping statements (while, do-while
   and for) to skip the current iteration of the loop and resume the next iteration .

   Syntax:
    continue;

   Example:
   3. Return statements:
      It is a special branching statement that transfers the control to the caller of the
      method. This statement is used to return a value to the caller method and terminates
      execution of method. This has two forms: one that returns a value and the other that
      can not return. the returned value type must match the return type of method.

       Syntax:
        return;
        return values;

       return; //This returns nothing. So this can be used when method is declared with
       void return type.
       return expression; //It returns the value evaluated from the expression.

       Example: Here Welcome() function is called within println() function which returns a
       String value "Welcome to roseIndia.net". This is printed to the screen.




Classes:-
A class is nothing but a blueprint or a template for creating different objects which defines its
properties and behaviors. Java class objects exhibit the properties and behaviors defined by
its class. A class can contain fields and methods to describe the behavior of an object.

Methods are nothing but members of a class that provide a service for an object or perform
some business logic. Java fields and member functions names are case sensitive. Current
states of a class’s corresponding object are stored in the object’s instance variables. Methods
define the operations that can be performed in java programming.

A class has the following general syntax:

<class modifiers>class<class name>
<extends clause> <implements clause>{
// Dealing with Classes (Class body)
<field declarations (Static and Non-Static)>
<method declarations (Static and Non-Static)>
<Inner class declarations>
<nested interface declarations>
<constructor declarations>
<Static initializer blocks>
}

Below is an example showing the Objects and Classes of the Cube class that defines 3 fields namely
length, breadth and height. Also the class contains a member function getVolume().

public class Cube {

          int length;
          int breadth;
          int height;
          public int getVolume() {
                return (length * breadth * height);
          }
}

How do you reference a data member/function?

This is accomplished by stating the name of the object reference, followed by a period (dot),
followed by the name of the member inside the object.
( objectReference.member ). You call a method for an object by naming the object followed
by a period (dot), followed by the name of the method and its argument list, like this:
objectName.methodName(arg1, arg2, arg3).

For example:

cubeObject.length = 4;
cubeObject.breadth = 4;
cubeObject.height = 4;
cubeObject.getvolume()

Class Variables – Static Fields
We use class variables also know as Static fields when we want to share characteristics across
all objects within a class. When you declare a field to be static, only a single instance of the
associated variable is created common to all the objects of that class. Hence when one object
changes the value of a class variable, it affects all objects of the class. We can access a class
variable by using the name of the class, and not necessarily using a reference to an individual
object within the class. Static variables can be accessed even though no objects of that class
exist. It is declared using static keyword.

Class Methods – Static Methods
Class methods, similar to Class variables can be invoked without having an instance of the
class. Class methods are often used to provide global functions for Java programs. For
example, methods in the java.lang.Math package are class methods. You cannot call non-
static methods from inside a static method.

Instance Variables
Instance variables stores the state of the object. Each class would have its own copy of the
variable. Every object has a state that is determined by the values stored in the object. An
object is said to have changed its state when one or more data values stored in the object have
been modified. When an object responds to a message, it will usually perform an action,
change its state etc. An object that has the ability to store values is often said to have
persistence.

Consider this simple Java program showing the use of static fields and static methods

// Class and Object initialization showing the Object Oriented concepts in Java
class Cube {

         int length = 10;
         int breadth = 10;
         int height = 10;
         public static int numOfCubes = 0; // static variable
         public static int getNoOfCubes() { //static method
                 return numOfCubes;
         }
         public Cube() {
                 numOfCubes++; //
         }
}

public class CubeStaticTest {

         public static void main(String args[]) {
                 System.out.println("Number of Cube objects = " + Cube.numOfCubes);
                 System.out.println("Number of Cube objects = "
                                + Cube.getNoOfCubes());
         }
}


Download CubeStaticTest.java

Output

Number of Cube objects = 0
Number of Cube objects = 0

Final Variable, Methods and Classes
In Java we can mark fields, methods and classes as final. Once marked as final, these items
cannot be changed.
Variables defined in an interface are implicitly final. You can’t change value of a final
variable (is a constant). A final class can’t be extended i.e., final class may not be subclassed.
This is done for security reasons with basic classes like String and Integer. It also allows the
compiler to make some optimizations, and makes thread safety a little easier to achieve. A
final method can’t be overridden when its class is inherited. Any attempt to override or hide a
final method will result in a compiler error.




Methods:-

Java Methods

   1. JavaScript type of Operator
      The JavaScript type of operator returns the datatype of an operand. You can see in the
      given example that we have used different variables to show the use of type of
      Operator.

   2. In Java, java.lang.reflect.*; package is required to import in the program to invoke
      the methods. As you can see here we are using reflect method, this could be either a
      class method or instance method and the usage of methods in Java is to access a single
      method either on class or interface.

   3. Generics Method in Java
      After going through the example, you will be able to declare and use generic methods
      in Java programming language. As you already know, generic method use parameter
      type declaration and that can be done using the <> syntax.

   4. JAVA Method Wait
      The Wait method in Java hold the thread to release the lock till the thread hold the
      object. The most important point is to be remember that wait method is used inside
      the synchronized code.

   5. Java Method Return Value
      The return statement is used to return the value within the body of method. The
      method declared void does not return any value. In case you try to get the return value
      from void .the code show you a compiler error.

   6. Java Method Synchronized
      The Java language Program supports multi threads. The synchronized is a keyword
      used in Java ensures that only one Java thread execute an object's synchronized
      method at a time.
Inheritance:-

Inheritance

To know the concept of inheritance clearly you must have the idea of class and its features
like methods, data members, access controls, constructors, keywords this, super etc.

As the name suggests, inheritance means to take something that is already made. It is one of
the most important feature of Object Oriented Programming. It is the concept that is used for
reusability purpose. Inheritance is the mechanism through which we can derived classes from
other classes. The derived class is called as child class or the subclass or we can say the
extended class and the class from which we are deriving the subclass is called the base class
or the parent class. To derive a class in java the keyword extends is used. To clearly
understand the concept of inheritance you must go through the following example.

The concept of inheritance is used to make the things from general to more specific e.g.
When we hear the word vehicle then we got an image in our mind that it moves from one
place to another place it is used for traveling or carrying goods but the word vehicle does not
specify whether it is two or three or four wheeler because it is a general word. But the word
car makes a more specific image in mind than vehicle, that the car has four wheels . It
concludes from the example that car is a specific word and vehicle is the general word. If we
think technically to this example then vehicle is the super class (or base class or parent class)
and car is the subclass or child class because every car has the features of it's parent (in this
case vehicle) class.

The following kinds of inheritance are there in java.

        Simple Inheritance
        Multilevel Inheritance

Pictorial Representation of Simple and Multilevel Inheritance




Simple Inheritance                    Multilevel Inheritance
Simple Inheritance

When a subclass is derived simply from it's parent class then this mechanism is known as
simple inheritance. In case of simple inheritance there is only a sub class and it's parent class.
It is also called single inheritance or one level inheritance.

eg.

class A {
  int x;
  int y;
  int get(int p, int q){
  x=p; y=q; return(0);
  }
  void Show(){
  System.out.println(x);
  }
}

class B extends A{
  public static void main(String args[]){
  A a = new A();
  a.get(5,6);
  a.Show();
  }
  void display(){
  System.out.println("B");
  }
}


Multilevel Inheritance

It is the enhancement of the concept of inheritance. When a subclass is derived from a
derived class then this mechanism is known as the multilevel inheritance. The derived class is
called the subclass or child class for it's parent class and this parent class works as the child
class for it's just above ( parent ) class. Multilevel inheritance can go up to any number of
level.
e.g.

class A {
  int x;
  int y;
  int get(int p, int q){
  x=p; y=q; return(0);
  }
  void Show(){
  System.out.println(x);
  }
}
class B extends A{
  void Showb(){
  System.out.println("B");
  }
}

class C extends B{
    void display(){
    System.out.println("C");
    }
    public static void main(String args[]){
    A a = new A();
    a.get(5,6);
    a.Show();
    }
}


Java does not support multiple Inheritance

Multiple Inheritance

The mechanism of inheriting the features of more than one base class into a single class is
known as multiple inheritance. Java does not support multiple inheritance but the multiple
inheritance can be achieved by using the interface.

In Java Multiple Inheritance can be achieved through use of Interfaces by implementing more
than one interfaces in a class.

super keyword

The super is java keyword. As the name suggest super is used to access the members of the
super class.It is used for two purposes in java.

The first use of keyword super is to access the hidden data variables of the super class hidden
by the sub class.

e.g. Suppose class A is the super class that has two instance variables as int a and float b.
class B is the subclass that also contains its own data members named a and b. then we can
access the super class (class A) variables a and b inside the subclass class B just by calling
the following command.

super.member;

Here member can either be an instance variable or a method. This form of super most useful
to handle situations where the local members of a subclass hides the members of a super class
having the same name. The following example clarify all the confusions.

class A{
  int a;
  float b;
  void Show(){
  System.out.println("b in super class:              " + b);
  }

}

class B extends A{
  int a;
  float b;
  B( int p, float q){
    a = p;
    super.b = q;
    }
    void Show(){
    super.Show();
    System.out.println("b in super class: " + super.b);
    System.out.println("a in sub class: " + a);
    }

    public static void main(String[] args){
    B subobj = new B(1, 5);
    subobj.Show();
    }
}


Output:

C:\>java B
b in super class: 5.0
b in super class: 5.0
a in sub class: 1

Use of super to call super class constructor: The second use of the keyword super in java is
to call super class constructor in the subclass. This functionality can be achieved just by using
the following command.

super(param-list);

Here parameter list is the list of the parameter requires by the constructor in the super class.
super must be the first statement executed inside a super class constructor. If we want to call
the default constructor then we pass the empty parameter list. The following program
illustrates the use of the super keyword to call a super class constructor.

class A{
  int a;
  int b;
  int c;
  A(int p, int q, int r){
  a=p;
  b=q;
  c=r;
  }
}

    class B extends A{
    int d;
    B(int l, int m, int n, int o){
    super(l,m,n);
    d=o;
    }
    void Show(){
    System.out.println("a = " + a);
    System.out.println("b = " + b);
    System.out.println("c = " + c);
    System.out.println("d = " + d);
    }
  public static void main(String args[]){
  B b = new B(4,3,8,7);
  b.Show();
  }
  }


Output:

C:\>java B
a=4
b=3
c=8
d=7




Exception Handling:-

Java Exception - Exception Handling in
Java

Exception, that means exceptional errors. Actually exceptions are used for handling errors in
programs that occurs during the program execution. During the program execution if any
error occurs and you want to print your own message or the system message about the error
then you write the part of the program which generate the error in the try{} block and catch
the errors using catch() block. Exception turns the direction of normal flow of the program
control and send to the related catch() block. Error that occurs during the program execution
generate a specific object which has the information about the errors occurred in the program.

In the following example code you will see that how the exception handling can be done in
java program. This example reads two integer numbers for the variables a and b. If you enter
any other character except number ( 0 - 9 ) then the error is caught by
NumberFormatException object. After that ex.getMessage() prints the information about the
error occurring causes.

Code of the program :

import java.io.*;

public class exceptionHandle{
  public static void main(String[] args) throws Exception{
  try{
  int a,b;
  BufferedReader in =
  new BufferedReader(new InputStreamReader(System.in));
    a = Integer.parseInt(in.readLine());
    b = Integer.parseInt(in.readLine());
    }
    catch(NumberFormatException ex){
    System.out.println(ex.getMessage()
    + " is not a numeric value.");
    System.exit(0);
    }
    }
}



Multithreading:-

Multithreading in Java

Introduction

So far you have learned about a single thread. Lets us know about the concept of
multithreading and learn the implementation of it. But before that, lets be aware from the
multitasking.

Multitasking :

Multitasking allow to execute more than one tasks at the same time, a task being a program.
In multitasking only one CPU is involved but it can switches from one program to another
program so quickly that's why it gives the appearance of executing all of the programs at the
same time. Multitasking allow processes (i.e. programs) to run concurrently on the program.
For Example running the spreadsheet program and you are working with word processor also.

Multitasking is running heavyweight processes by a single OS.

Multithreading :

Multithreading is a technique that allows a program or a process to execute many tasks
concurrently (at the same time and parallel). It allows a process to run its tasks in parallel
mode on a single processor system

In the multithreading concept, several multiple lightweight processes are run in a single
process/task or program by a single processor. For Example, When you use a word
processor you perform a many different tasks such as printing, spell checking and so on.
Multithreaded software treats each process as a separate program.

In Java, the Java Virtual Machine (JVM) allows an application to have multiple threads of
execution running concurrently. It allows a program to be more responsible to the user. When
a program contains multiple threads then the CPU can switch between the two threads to
execute them at the same time.
For example, look at the diagram shown as:




In this diagram, two threads are being executed having more than one task. The task of each
thread is switched to the task of another thread.

Advantages of multithreading over multitasking :

      Reduces the computation time.
      Improves performance of an application.
      Threads share the same address space so it saves the memory.
      Context switching between threads is usually less expensive than between processes.
      Cost of communication between threads is relatively low.

Different states implementing Multiple-Threads are:




As we have seen different states that may be occur with the single thread. A running thread
can enter to any non-runnable state, depending on the circumstances. A thread cannot enters
directly to the running state from non-runnable state, firstly it goes to runnable state. Now lets
understand the some non-runnable states which may be occur handling the multithreads.

      Sleeping ? On this state, the thread is still alive but it is not runnable, it might be
       return to runnable state later, if a particular event occurs. On this state a thread sleeps
       for a specified amount of time. You can use the method sleep( ) to stop the running
       state of a thread.

         static void sleep(long millisecond) throws InterruptedException
      Waiting for Notification ? A thread waits for notification from another thread. The
       thread sends back to runnable state after sending notification from another thread.

         final void wait(long timeout) throws InterruptedException
         final void wait(long timeout, int nanos) throws InterruptedException
         final void wait() throws InterruptedException

      Blocked on I/O ? The thread waits for completion of blocking operation. A thread
       can enter on this state because of waiting I/O resource. In that case the thread sends
       back to runnable state after availability of resources.

      Blocked for joint completion ? The thread can come on this state because of waiting
       the completion of another thread.

      Blocked for lock acquisition ? The thread can come on this state because of waiting
       to acquire the lock of an object.

Collections:-
A collection is simply an object that groups multiple elements into a single unit. It is also
called as a container sometimes.


Introduction to Collections API

As the name indicates, collections is a group of objects known as its elements. Basically it is
a package of data structures that includes ArrayLists, LinkedLists, HashSets, etc. A
collection is simply an object that groups multiple elements into a single unit. It is also called
as a container sometimes. It is used to store, retrieve, manipulate, and communicate aggregate
data. Typically, it represents data items that form a natural group and allows duplicate
elements while others do not. It consists of both ordered and unordered elements. There is no
direct implementation of this interface however SDK provides implementations of more
specific sub interfaces like Set and List. The manipulation and passing of collections is done
by this interface.

The Two "standard" constructors should be provided by all the general-purpose Collection
implementation classes. These classes typically implement Collection indirectly through one
of its sub interfaces.

   1. Void (no arguments) constructor which creates an empty collection.
   2. Constructor with a single argument of type Collection, which creates a new collection
      with the same elements as its argument.

The user can copy any collection using void constructor to produce an equivalent collection
of the desired implementation type. As interfaces cannot contain constructors there is no way
to enforce this convention. However all of the general-purpose Collection implementations
comply this in the Java platform libraries.
The Java Collections API:

Java Collections of API (Application Programming Intreface) Consists of several interfaces,
and classes that implement those interfaces, within the java.util package. It provides tools for
maintaining a data container of objects. Each primitive value must be wrapped in an object of
its appropriate wrapper class (Boolean, Character, Integer, Double, etc.) to maintain a
collection of primitive data. It is an alternative tool to the creation of custom data structures.

You must be familiar with collections if you have worked with Java programming language .
Collection implementations included Vector, Hashtable, and array are available in earlier
(pre-1.2) versions of the Java platform, but those versions do not include the collections
framework. Hence the new version of the Java platform contains the collections framework.




I/O streams:-
The Java I/O means Java Input/Output. It is provided by the java.io package. This
package has an InputStream and OutputStream. Java InputStream is defined for
reading the stream, byte stream and array of byte stream.


Java I/0 Examples

   1. What is Java I/O?
      The Java I/O means Java Input/Output. It is provided by the java.io package. This
      package has an InputStream and OutputStream. Java InputStream is defined for
      reading the stream, byte stream and array of byte stream.
   2. Classes and Interfaces of the I/O Streams
      The following listing of classes provided by the java.io package shown in the given
      table.

   3. Reading Text from the Standard Input
      Java provides the standard I/O facilities for reading text through either from the file or
      from the keyboard on command line. This program illustrates how to use standard
      input to read the user input.
   4. Working With the Files
      The File class deals with the machine dependent files in a machine-independent
      manner i.e. it is easier to write platform-independent code that examines and
      manipulates files using the File class. This class is available in the java.lang package.
         o Create a File
         o Constructing a File Name path
         o Read the File
         o Write to a File
         o Appending to a File
         o Getting the Size of a File
         o Count lines of a particular file
       o   Renaming a File or Directory
       o   Copying a File to Another File
       o   Copying Multiple Files
       o   Moving a File or Directory to Another Directory
       o   Deleting a File or Directory
       o   Change a File timestamp
       o   Create a Temp File
       o   Delete a Temp File
       o   Getting an absolute path and Parents of a Filename

5. Working with a Directory
   In the section, you will learn how a directory is created. Apart from this, you will also
   be aware from some manipulations that are performed
   on a directory.
       o Creating a Directory
       o Copying a Directory or file
       o Traversing files and directories
       o Getting the Current Working Directory
       o Getting the Modification Time of a File or Directory
       o Listing Files or Subdirectories
       o Deleting a File




6. Filter I/O Streams
   Like I/O streams, Filter streams are also used to manipulate the data reading from an
   underlying stream.. Apart from this, it allows the user to make a chain using multiple
   input stream so that, the operations that are to be applied on this chain, may create a
   combine effects on several filters.
       o Introduction
       o Write to a file
       o Read the file
       o Another Streams

7. Overview of I/O Data Streams
   Data streams are filtered streams that perform binary I/O operation on primitive data
   type values ( boolean, char, byte, short, int, long, etc.) as well as on String values. If
   you need to work with data that is not represented as bytes or characters then you can
   use Data Streams.
       o Working with PrintStream

8. Using a Random Access File
   n this section, you will learn about the Random Access File class provided by java.
   io package. This is a class that allows you to read and write arbitrary bytes, text, and
   primitive Java data types from or to any specified location in a file.

9. Converting a Filename Path to a URL
   In this section, you will learn, how a Filename path is converted to a URL and vice
   versa . URL stands for Uniform Resource Locator.
10. Making Tokens of a Java Source Code
    In Java, The StreamTokenizer class is used for simple parsing of a Java source file
    into tokens. This class takes an input stream, breaks up the ASCII text in a file and
    parses it into "tokens". It allows the tokens to be read one at a time.

11. Introduction to Encoding
    Java programs use Unicode text internally. It supports standard UTF-8 when reading
    and writing strings through the InputStreamReader and the OutputStreamWriter.



       o   Reading UTF-8 Encoded Data
       o   Writing UTF-8 Encoded Data
       o   Reading ISO Latin-1 Encoded Data
       o   Writing ISO Latin-1 Encoded Data

12. Serializing an Object
    Serialization is the process of saving an object in a storage medium (such as a file, or
    a memory buffer) or to transmit it over a network connection in binary form.

13. Deserializing an Object
    The opposite operation of the serialization is called deserialization i.e. to extracting
    the data from a series of bytes is s known as deserialization

14. Delete file or Directory
    In this example we are discussing the deletion of a file or a directory by using a java
    program. We pass the file name or the directory name to which we want to delete.

15. Downloading and Viewing html source of a page i.e. running on the server
    This section illustrates you the procedure of viewing complete html code of a page i.e.
    running on the server.

16. URL file Download and Save in the Local Directory
    This Program file download from URL and save this Url File in the specified
    directory. This program specifies the directory path where the files to be stored as
    first command line argument and second command line arguments specifies URL File
    to be stored.

17. Create XML file from flat file and data insert into database
    In this section, we have developed an application to create xml file from flat file and
    data insert into database in Java.

18. Miscellaneous
       o Compressing Streams
       o Zip File
       o Zip Folder
       o Unzip File
       o Code for Garbage Collection
   19. Delete File Example
       In this section, you will learn how to delete a file.

   20. Buffer Reader
       In this section you will learn how to read line by line data from a file using
       BufferedReader.

   21. File Input Stream
       Java has Two types of streams- Byte & Characters.

   22. File Output Stream
       As we discussed earlier, java has two kinds of streams- Byte & Characters.

   23. Last Modified Date
       This section contains the detail about how to get the last modification date of a file.

   24. Java File Handling
       For file handling in java, the package known as java.io is available.

   25. File Compare
       In this section, we will discuss how to compare pathname of two file for the equality
       of their path.

   26. Read File Buffered Writer Example
       In this section, you will learn how to write to a file using BufferedWriter.

   27. Copy File Example
       In this section, you will learn how to copy content of one file into another file.




AVVT:-

Java AWT Package Example

In this section you will learn about the AWT package of the Java. Many running examples
are provided that will help you master AWT package. Example provided are supported with
tested code.

   1. Graphical User Interfaces
      A class library is provided by the Java programming language which is known as
      Abstract Window Toolkit (AWT).
2. What is AWT in java
   In this section, you will learn about the java.awt.*; package available with JDK.
   AWT stands for Abstract Windowing Toolkit.
3. Describe the AWT Components
   In this section you will learn about the different components available in the Java
   AWT package for developing user interface for your program.
4. AWT Components
   The class component is extended by all the AWT components. More of the codes
   can be put to this class to design lot of AWT components. Following are the AWT
   components:
      i.    Canvas
     ii.    Checkbox
    iii. Label
    iv.     Scrollbar
     v.     TextField

5. Common Component Methods
    The common methods of AWT components are as follow:
6. Containers
    As discussed earlier a container is a component that can be nested. The most widely
    used Panel is the Class Panel which can be extended further to partition GUIs.
7. Describe different types of event to provide by the AWT Components in java
     There are many types of events that are generated by your AWT Application. These
    events are used to make the application more effective and efficient. Generally, there
    are twelve types of event are used in Java AWT.
8. Events
    In this section, you will learn how to handle events in Java awt. Events are the integral
    part of the java platform.
9. Event Adapters
    There are some event listeners that have multiple methods to implement. That is some
    of the listener interfaces contain more than one method.
10. Button Pressing Example
    In the program code given below, the Frame contains three buttons named -
    "Bonjour", "Good Day", "Aurevoir".
11. Adapters Example
    In the following program code, the adapter class has been used. This class has been
    used as an anonymous inner class to draw a rectangle within an applet.
12. GUI-based Applications
    In this section you will learn about how to create a window for your application. You
    need to define a subclass of Frame to create a window for your application.
13. Menus
    We can also develop an application with a Menu. As a name indicates a Menu
    consists of Menu objects.
14. Menu Shortcuts
    The MenuItem class also provides a feature of menu shortcuts and speed keys.
15. Pop-up Menus
    A PopupMenu is similar to a Menu as it contains MenuItem objects. The Pop-up
    Menu can be popped over any component while generating the appropriate mouse
    event rather than letting it appear at the top of a Frame.
16. Creating a Frame
    This program shows you how to create a frame in java AWT package. The frame in
    java works like the main window where your components (controls) are added to
    develop a application. In the Java AWT, top-level windows are represented by the
    Frame class.

17. Setting the Icon for a Frame
    Here, you will learn how to set the icon of the frame. This program is the detailed
    illustration to set the icon to the frame.

18. Setting the close button operation for the frame
    In this section, you will learn how to implement the close button of any frame or
    window in java application. By default the close button of the frame is not in working
    state.

19. Making a Frame Non-Resizable
    This program illustrates you how to make a frame non resizable. It means that the
    disabling the maximize button of the frame.

20. Removing the Title Bar of a Frame
    Here, you will learn how to display the frame or window without title bar in java. This
    type of the frame is mostly used to show the splash screen at starting of the
    application.

21. Creating a Container
    This program illustrates you how to create a container. Container contains several
    control or tools for develop your application. All the controls used in your application
    are the container for one another.

22. Changing the Cursor
    Here, you will learn how to change the mouse cursor in java. Changing the cursor
    means showing cursor in many different shapes for the different objects.

23. Draw Image in Frame
    In this section, you will learn how to display image on the frame. This program shows
    you how to display image in your application.

24. Handling Focus Changes
    In this section, you will learn about handling the focus changes in java. This section
    shows you how the event be handled according to the focuses and to find out whether
    the component got the focus or lost the focus.

25. Handling Mouse Clicks
    In this section, you will learn about handling the mouse click event in the awt
    application.

26. Handling Action Events
    In this section, you will learn how to handle events in java awt. Here, this is done
    through the java.awt.*; package of java. Events are the integral part of the java
   platform.

27. Handling Key Presses
    In this section, you will learn about the handling key press event in java. Key Press is
    the event is generated when you press any key to the specific component.

28. Item Events
    In this section, you will learn about handling item events in java. This demonstrates
    that the event generated when you select an item from the group of the items.

29. How to use KeyListener
    In this section, you will learn how to handle different key events on the Java Awt
    component by using the event handling in Java. When the given program is executed
    then you will see the several key events these are applied on the component like the
    key pressed, key release and so on.

30. Simple Form in Java
    This is a simple program of java awt package which constructs a look like a form by
    using various java component. In this section, you will learn how to create it. This is
    done by using java gui programming using Classes or APIs of java awt package.

31. Hiding Frame in Java
    This section illustrates you how to hide the Java Awt frame. Here, you have seen in
    the given following example that provides you the complete code of the program.

32. How to Create Button on Frame
    In this section, you will learn how to create Button on frame the topic of Java AWT
    package. In the section, from the generated output of the following program, complete
    window or frame is created in the ButtonText class that is the main class where the
    main() method lies. This part of the topic will show a simple command button labeled
    with the text "Submit" when the program will be executed.

33. How to create CheckBox On frame
    This is very simple java program. In this section, you will learn how to create
    CheckBox on the frame. In the Java AWT, top-level windows are represented by the
    CheckBox class. This program provides you complete illustration with the full
    description. If you are fresher in java awt programming then you can learn in very
    efficient manner.

34. Choice Option (Combo) In Java
    In this section, you will learn how to create Drop-Down List by using Java AWT
    package.

35. Arcs Drawing In Java
    In this section, you will learn how to create arcs diagram in java awt package. The
    Java program uses Arcs2D class, arcs2D is the abstract superclass for all objects that
    store a 2D arc defined by a bounding rectangle, start angle, angular extent and a
    closure type.
36. BorderLayout Example In Java
    In this section, you will learn how to create BorderLayout in java awt package. The
    Border Layout is arranging and resizing components to set in five position which is
    used in this program.

37. Cubic Diagram In Java
    In this section, you will learn how to create Cubic diagram. The Java2D API
    provides you several classes that defines common Geometry object as a coordinate
    component. The Java Drawing program depends on the Java2D API class, and this
    class is support by the "java.awt.geom" package.

38. How to Create Circle In Java
    This is a simple program of java awt. In this section, you will learn how to create
    Circle Diagram. The java circle is the most fundamental abstractions in a Java 2D in
    the supported java.awt.shape package.

39. How to Create CurveDraw In Java
    In this section, you will learn how to create CurveDraw in java.awt package. This
    class, supported by the java.awt.geom package, enables you to create a quadratic or
    cubic segment. Here, you will see in the following example that provide you complete
    code of the program.

40. How to Create LineDraw In Java
    This is a simple java program . In this section, you will learn how to create Line
    Drawing. This program implements a line Drawing component. A java program
    explains the stroke line i.e. how to make thick and thin line. For this we have used
    BasicStroke class. This object is passed to the setStroke() method.

41. RadioButton In Java
    In this section, you will learn how to create Radio Button on the frame. The java
    AWT , top-level window, are represent by the CheckBoxGroup. A java program
    provides you CheckboxGroup. In this program, you will see how to create and show
    the Checkboxgroup component on the frame.

42. Rectangle Image In Java
    In this section, you will learn how to create rectangle image. This program used the
    Graphics2D class which extends the Graphic class and control all geometry or
    coordinate transformation and color management, text layout. The Java programming
    in java 2D API provides several classes.

43. Textarea Frame In Java
    In this section, you will learn how to create TextArea on the frame. This program uses
    the TextArea class of java.awt package. Here, we are going to create TextArea
    object. TextArea object is a multiline region. It displays text only. You can read and
    edit the text only.

44. Image Demo
    This section simply display the image demo that means multiple images and its name
    are based on the frame to a particular location. For displaying images demo first of all
      you will need multiple images that have to be displayed on the frame.

  45. Image Size
      This Java awt (Abstract Windowing Toolkit) tutorial describes about the image size.
      This is an actual representation of object. Simply, it helps us to feel associated with an
      object on the frame.

  46. Paint Icon
      This section provides you to paint an image on the frame. Paint means draw an image
      and set its on the frame to the specified location according to its x coordinate and y
      coordinate.

  47. RanderingHints Graphics
       This Java tutorial teaches you about adding the rendering hints to a graphics on the
      frame. The rendering hints uses the Graphics2D and creates the following image.

  48. Line Animation
      In this example we are creating an animated line. The color of line is changing
      alternatively.

  49. Beep Example
      Lets learn how to create beep using java.

  50. Open The Default Editor to Edit the File
      This section, you will see the method of opening the file in the default editor to edit
      and save the file. Here an example has been provided with the complete Java code for
      illustrating all the things that helps to open the file in the default editor to edit the file.

Apolet Programming:-
Java Applet
     Java is a general purpose programming language.
     A Java program is created as a text file with .java extension.
     It is compiled into one or more files of bytecodes with .class extension.
     Bytecodes are a set of instructions similar to machine code of a specific machine but
      it can be run on any machine that has a Java Virtual Machine (JVM). JVM interprets
      bytecodes.
     JVM was first implemented on Sparc/Solaris and PC/Win32. Now ported to many
      other platforms.
     Java applets are Java programs that are retrieved and executed by web browsers
      through the JVM under tight secure environment.
     Web browsers retrieve Java applets according to following tags in the web pages:


      <applet code=ResPlotApplet.class width=600 height=500> deprecated or the new
      more general,
      <object codetype="application/java" classid="java:ResPlotApplet.class" width=600
          height=500>
     <param> are used to specify parameters for the applet. For example,


      <APPLET CODE="Animator.class"
         WIDTH="aNumber"       -- the width (in pixels) of the widest frame
         HEIGHT="aNumber">       -- the height (in pixels) of the tallest frame
      <PARAM NAME="IMAGESOURCE"
         VALUE="aDirectory">    -- the directory that has the animation frames (gif,
      jpg)

     All other types of java programs are called Java applications.
     Examples:
     Network Restoration Applet: User specifies two end node of a failed link. The applet
      retrieves the simulation results of two network restoration algorithms (twoprong and
      rreact) in two corresponding files at original web server site, and plot the results.
     SUN Java demos:
          o MoleculeViewer
          o SimpleGraph
          o SortDemo
          o BarChart
          o Animator
          o JumpingBox


Java is safe
     When a Java applet is downloaded, the bytecode verifier of the JVM verifies to see if
      it contains bytecodes that open, read, write to local disk.
     Java applet can open new window but they have Java log to prevent them from being
      disguised as system window (for stealing password).
     Java applet is not allowed to connect back to other servers except that hosts itself.
     This secure execution environment is called sand box model.
     JDK 1.1 extends this tight security with digitally signed applet using jar file.
     More detailed fine grained security levels are planned for future release.

Java Development Kit
     The current release is JDK 1.1.7A. It is free for download, containing documents,
      demos, library, bin/utilities, and Java API packages.
     Java Application Programming Interface (API) consists of classes for programming:
         o java.applet.*: for applet context and interface to browsers
         o java.lang.*: variable, string manipulation, exception handing, thread.
         o java.io.*: File I/O through [buffered] input/outputStream,
         o java.awt.*: Abstract Window Toolkit (AWT) for window/GUI design, image
             creation and manipulation
         o java.util.*: hashtable, stringTokenizer (simple split), date, random, bitset,
             vector.
         o java.net.*: url, urlconnection for connecting to original web servers, socket
         o java.math.*: math functions.
         o java.sql: for Java-Database interface
     Extended APIs:
         o Media API for sound, video, 3D, VRML
         o Commerce API
         o Servlet API
     JDK 1.2 will soon be released.

Java Applet Development Environment
     Make sure the CLASSPATH in your autoexec.bat does not contain local directory, or
      just comment it out. They triggers the security alarm saying that the applet trying
      access to local drive.
     Use Jbuilder2 (in our PC lab). It contains
          o java source code editor
          o class browser
          o debugger
          o visual GUI design tool similar to VBasics.
          o wizard for guiding the java application, java applet, java class development.
          o extensive java beans and libraries for Database access and enhanced GUI
               design.
     Create new Java Applet by
          o first create a project folder by
                    select the File/New Project, the project wizard window appears
                    replace the untitle string in the file textfield with your project name,
                       say cs301hw6.
                    replace the title of the project, click finish, a project template will
                       appear.
          o then create the Java applet template by
                    select File/New
                    click on the Applet icon
                    fill in the information in the applet creation dialog box (choose the core
                       Java and Swing only option)
                    write java code in the created template.
                    control-s to save file the <jbuilder2 home>myprojects\cs301hw6
                       directory, where <jbuilder2home> is the directory setup for jbuilder2
                       in your system.
                    select build/make "CompareCookieSales.java", it will compile the
                       code, show the error if any, and save the class byte code in
                       <jbuilder2home>myclasses\CompareCookieSales.class
                    ftp the .java code and .class code (note there may be more than one
                       .class generated) back to the web server directory.
                    Make sure the case of the class file name is correct after the file
                       transfer.
     Download JDK1.1.7A (you can also try JDK1.2RC2 a beta release) to your own PC.
     Use text editor to create .java source code.
     Reference document web page,
      http://java.sun.com/products/jdk/1.1/docs/api/packages.html
     Use " javac ResPlot.java" to compile the java code.
     Create a web page with the object or applet tag to reference the Java Applet.
Basics of Applet Programming
Operators and Their Precedence

The following table shows the precedence assigned to Java's operators. The operators in this
table are listed in precedence order: the higher in the table an operator appears, the higher its
precedence. Operators with higher precedence are evaluated before operators with a relatively
lower precedence. Operators on the same line have equal precedence.
postfix operators       [] . (params) expr++ expr--

unary operators         ++expr --expr +expr -expr ~ !

creation or cast        new (type)expr

multiplicative          * / %

additive                + -

shift                   << >> >>>

relational              < > <= >= instanceof

equality                == !=

bitwise AND             &

bitwise exclusive OR ^
bitwise inclusive OR |
logical AND             &&

logical OR              ||

conditional             ? :

assignment              = += -= *= /= %= &= ^= |= <<= >>= >>>=


When operators of equal precendence appear in the same expression, some rule must govern
which is evaluated first. In Java, all binary operators except for the assignment operators are
evaluated in left to right order. Assignment operators are evaluated right to left.

Control Flow Statements

A statement such as the while statement is a control flow statement, that is, it determines the
order in which other statements are executed. Besides while, similar to C, the Java language
supports several other control flow statements (except the exception handling), including:
   Statement                     Keyword
decision making     if-else, switch-case

loop                for, while, do-while

exception           try-catch-finally, throw
miscellaneous      break, continue, label:       , return

Note: Although goto is a reserved word, currently the Java language does not support the
goto statement.

Handling errors with Expression using Try, Catch, and Throw

Basic Steps:

      All Applet source code starts with


       import java.applet.*;
       and other import statements for packages used in the applet such as
       import java.awt.*; import java.io.*; import java.lang.*; import java.net.*; import
       java.util.*;

      It then starts with a class definition like:


       public class Chart extends java.applet.Applet {
         // followed by a list of variables or objects declaration
         //
         Button b1 = new Button("play");
         Button b2 = new Button("stop");
         Button b3 = new Button("resume");
         TextField tf = new TextField("Message here", 50);
         TextArea ta = new TextArea("please wait...", 10, 40);
       }

      The main class contains four basic Applet methods:


       public void init() {
          // for any initialization code performed during loading time of the applet
          // such as loading graphics, initialize variables, creating objects
          // add() is used to insert the objects into the area allocated for the applet
         add(b1); add(b2); add(b3); add(tf); add(ta);
       }
       public void start() {
          // implement the main action of the applet behavior
          // it is also called by browser to restart after it was stopped.
       }
       public void stop() {
          // stop an applet's execution but leaves resources intact so it can restart.
       }
       public void destroy() {
          // release all its resources
           // typically happens when the user leaves the page containing the applet.
       }

      Many Applet only needs to implement init()
      For control and user input, Button, TextField, TextArea, Canvas objects are created in
       init()


       and special method action() is called when event happens
       public boolean action(Event e, Object o) {
          if (e.target instanceof Button) {
              String s = (String) o;
              if (s.equals("play") {
                 tf.setText("play button is pushed");
             } else if (s.equal("stop") {
                 ta.setText("stop button is pushed");
             } else {
                 ta.appendText("resume button is pushed");
             }
              return true;
         }
          return false;
       }

      Try this basic example.

Abstract Window Toolkit (AWT)
Tutorial from Netscape

Using AWT Components: http://owl.uccs.edu/~cs301/java/awt/oldui/components/using.html

Layout the Components in a container:
http://owl.uccs.edu/~cs301/java/awt/oldui/layout/index.html

Note that there are new GUI packages such swing and Java 2D graphics recommended by
Netscape. They are great for making Java applications with GUI, but there are still a lot of
browsers do not support that. They require JDK1.2 compatible viewer or Java plug in.

"Java Plug-in software enables enterprise customers to direct Java applets or JavaBeansTM
components on their intranet web pages to run using Sun's Java Runtime Environment (JRE),
instead of the browser's default Java runtime. This enables an enterprise to deploy Java
applets that take full advantage of the latest capabilities and features of the Java platform and
be assured that they will run reliably and consistently. " --
http://java.sun.com/applets/index.html.


Using JFC/SWING to create GUI
The swing components in Java Foundation Classes (JFC) is the new package in JDK1.1 and
JDK1.2 for supporting GUI design in Java applications and applets.
It provides much more features to those of AWT. For examples,

       allow images on buttons/labels,
       dynamically change of borders,
       component can be round,
       specify look and feels (Java, Windows, CDE/Motif).
       wider selection of components
       not using native code (more portable)


Unfortunately, Sun recommends that SWING and AWT components not mix. Their drawing
sequence are basically different. "Heavyweight" AWT components such as menu,
scrollpane, canvas, and panel always draw on top of "lightweight" SWING components.

Tutorial on using GridBagLayout.

Note that the current tutorial on java.sun.com is going through major revision. Some web
pages, such as the layout manager tutorial, event hung the whole browser. Use them with
caution. 12/3/98.


Example for using GridBagLayout and submit data to a
CGI script
http://owl.uccs.edu/~cs301/java/Register.html and Register.java

Goal:

       Illustrate the use of the GridBagLayout manager and AWT components.
       Learn how to exchange data between Applet and CGI script using URL.

How we arrange the GridBagLayout using GridBagConstraints:

       Here we create a title as a Label and set gbc.anchor = GridBagConstraints.NORTH.
       We have login and address Labels and set their gbc.anchor =
        GridBagConstraints.WEST and gbc.gridwidth = 1.
       The login TextField and address TextArea are set with gbc.grdiwidth =
        GridBagConstraints.REMAINDER.
       The submit Button is set with gbc.anchor = GridBagConstraints.CENTER and
        padded with 10 pixels on each side using gbc.insets = new Insets(10,10,10,10);
       Finally the return result TextArea is set with gbc.anchor =
        GridBagConstraints.SOUTH and gbc.grdiwidth =
        GridBagConstraints.REMAINDER.

Basic steps for using the applet:
       When the submit button is hit, the action method first performs www-url-encode on
        the content of address TextArea, then puts the fields of the login and address in the
        name-value pair format attached at the end of the url.
       Create a URL with it, which in effect submit the data the corresponding CGI script on
        the server side.
       The registerData.pl saves the data in a file and return a web page that is then
        displayed in the result TextArea.

Example for plotting the cookie sale of a particular year.
http://owl.uccs.edu/~cs301/java/plotdemo/CookieSales.html and CookieSales.java.

Goal:

       Learn how to use the graphic drawing capability of the AWT.
       Learn how to retrieve data files from the web server.

Here are the basic steps for using the Applet:

       After the user selects the year in the choice menu and hits the plot button, the action
        method creates the url string by concatenating
        http://owl.uccs.edu/~cs301/java/plotdemo/data/ with CookieSale<year>.
       It then creates an URL object with the string and open a DataInputStream for reading
        the 12 month sale data from the web server into an array.
       Each line of the data file contains the month and box numbers of the cookie sale.
       The data file is displayed in the contents TextArea.
       It then sets the array in the CookieSalesCanvas class and asks it to plot the bar chart
        based on the data.
       drawRect() and fillRect() are used to draw the bar of each month.

Reasons for Extending Canvas Class

       For AWT components, we do not have extend classes unless there is a special need.
       For plots using Canvas class, we have a special requirement for handling the
        redrawing when the part or whole of the canvas area is destroyed due to the resizing
        of the applet or window hierarchy changes (other window pops up).
       Those destroyed areas need to be redrawn.
       The paint(Graphics g) method is designated for handling the redrawing and the first
        drawing of the area.
       It will be given the area that needs to be redrawn.
       It needs to know how to redraw the area --> needs to have access to the original
        source data.
       Therefore, we extend the canvas class with additional variables, such as Year and
        Sv[][] for holding a copy of the original source data.
       Here we use a setValue() to copy the source data from the applet to
        CookieSalesCanvas.
       In the paint(), we use the basic drawing functions create the content.

   
Debug Java Applet
     Use showStatus() which shows string on browser's status window.
     Create a TextArea or TextField for displaying intermediate results.
     Use JDB that comes with JDK.
     Use tools such as Jbuilder, Visual cafe, MS J++.
                         NETWORKING
Connecting to a Server:-

Connecting to the server




An image of a server with clients connected to it.


Building a client application
For this second part of the tutorial we will be building a client application to connect to the
server built in the first tutorial. The client application will connect to the server using sockets
much like the server used to connect to the client. Again, we will be using a PrintWriter to
write information to the server and we will be using a BufferedReader to read information
sent from the server. If you have not already then read the 1st part of the tutorial. Okay, let's
go!

Sockets
The way we will use a socket for the client-application will be a little different because,
instead of using a socket to receive a connection we will be using a socket to connect to the
server. Here is how we set up a socket to connect to the server:

?

1Socket socket = new Socket("localhost",5000);


The part of the code where I placed "localhost" is where you place the IP address of the
server. Since it will be easy to run the server and the client on the same computer I will use
localhost. Later on I will explain how to connect to the server from a different computer.

Now, you should understand everything in here, most of it is similar to what we did to set up
the server. Here you go:

?
    import java.io.*;
1
    import java.net.*;
2
    //We need a Scanner to receive input from the user
3
    import java.util.Scanner;
4

5
    public class Client
6
    {
7       public static void main(String[] args)

8       {

9           new Client();

10      }

11

12      public Client()

        {
13
        //We set up the scanner to receive user input
14
            Scanner scanner = new Scanner(System.in);
15
            try {
16
                Socket socket = new Socket("localhost",5000);
17
                PrintWriter output = new
    PrintWriter(socket.getOutputStream(), true);
18
                BufferedReader input = new BufferedReader(new
19InputStreamReader(socket.getInputStream()));

20

21              //This will wait for the server to send the string to the
    client saying a connection
22
                //has been made.
23
                String inputString = input.readLine();
24
                System.out.println(inputString);
25
                //Again, here is the code that will run the client, this will
    continue looking for
26
                //input from the user then it will send that info to the
27server.
28               while(true) {

29                    //Here we look for input from the user

                      String userInput = scanner.nextLine();
30
                      //Now we write it to the server
31
                      output.println(userInput);
32
                 }
33
            } catch (IOException exception) {
34
                 System.out.println("Error: " + exception);
35          }

36     }

37}

38



The Explanation
The biggest difference between this and the server is that we use a scanner to receive input
from the user. Other than that everything should be easy to understand. One confusing thing
may be why we include this line:

?

1String inputString = input.readLine();


You may be thinking, "Why are we waiting for input from the server?!? Aren't we supposed
to be sending the server information." Well, remember this line we put into the server code to
tell the client that he/she has connected?

?

1output.println("You have connected at: " + new Date());


Well, we need to receive that information and we do that by getting the information from the
server.

Much like the server we have a while loop that will continue running except that this while
loop waits for user input then prints it out to the server.

Try running it!
Try running this code. First run the server, then run the client. What should happen is that
after you run the client the server will acknowledge that the client has connected and then
whenever you type anything into the client it should appear on the server.

So, run the server, then run the client, the type stuff into the client, hit enter, and watch it
appear on the server!!!!!

What if I want to run it across two different computers?
Well, this isn't that hard but does complicate the process a little bit. First you need to set up
port-forwarding for your router and have your router port-forward for port 5000 because that
is the port we will be connecting through. This is a great site for figuring out how to port-
forward for your specific router. Next, you can't have the client connect using "localhost" so
delete "localhost" in your socket connection code and replace it with your ip address. Here is
an example below:

Replace this:



?

1Socket socket = new Socket("localhost",5000);


with this:

?

1Socket socket = new Socket(<Your IP Address here>,5000);


You can find your IP Address by going here. Just paste your IP Address where I said <Your
IP Address here> and you should be good to go.

Once you have done that then run the server code on one computer and run the client code on
another. It should work across computers. In fact, this would work all the way around the
world!!!!!!

Hooray!!!
Yay! You've made a server and you can connect to it!!!!!! But wait... what about chat? This
server doesn't really let you chat with anyone and only one person can connect to the server at
a time. Well, have no fear, Part 3 of the tutorial is here!!!!!

Download the code!
You can download the code for the server and the client here. Again, pardon the wait.
Implementing Servers:-
This section shows you how to write a server and the client that goes with it. The server in the
client/server pair serves up Knock Knock jokes. Knock Knock jokes are favored by children
and are usually vehicles for bad puns. They go like this:

Server: "Knock knock!"
Client: "Who's there?"
Server: "Dexter."
Client: "Dexter who?"
Server: "Dexter halls with boughs of holly."
Client: "Groan."

The example consists of two independently running Java programs: the client program and
the server program. The client program is implemented by a single class,
KnockKnockClient, and is very similar to the EchoClient example from the previous
section. The server program is implemented by two classes: KnockKnockServer and
KnockKnockProtocol, KnockKnockServer contains the main method for the server program
and performs the work of listening to the port, establishing connections, and reading from and
writing to the socket. KnockKnockProtocol serves up the jokes. It keeps track of the current
joke, the current state (sent knock knock, sent clue, and so on), and returns the various text
pieces of the joke depending on the current state. This object implements the protocol-the
language that the client and server have agreed to use to communicate.

The following section looks in detail at each class in both the client and the server and then
shows you how to run them.

The Knock Knock Server
This section walks through the code that implements the Knock Knock server program. Here
is the complete source for the KnockKnockServer class.

The server program begins by creating a new ServerSocket object to listen on a specific
port (see the statement in bold in the following code segment). When writing a server, choose
a port that is not already dedicated to some other service. KnockKnockServer listens on port
4444 because 4 happens to be my favorite number and port 4444 is not being used for
anything else in my environment:

try {
    serverSocket = new ServerSocket(4444);
}
catch (IOException e) {
    System.out.println("Could not listen on port: 4444");
    System.exit(-1);
}
ServerSocket     is a java.net class that provides a system-independent implementation of the
server side of a client/server socket connection. The constructor for ServerSocket throws an
exception if it can't listen on the specified port (for example, the port is already being used).
In this case, the KnockKnockServer has no choice but to exit.

If the server successfully binds to its port, then the ServerSocket object is successfully
created and the server continues to the next step--accepting a connection from a client (shown
in bold):

Socket clientSocket = null;
try {
    clientSocket = serverSocket.accept();
}
catch (IOException e) {
    System.out.println("Accept failed: 4444");
    System.exit(-1);
}

The accept method waits until a client starts up and requests a connection on the host and
port of this server (in this example, the server is running on the hypothetical machine taranis
on port 4444). When a connection is requested and successfully established, the accept
method returns a new Socket object which is bound to the same local port and has its remote
address and remote port set to that of the client. The server can communicate with the client
over this new Socket and continue to listen for client connection requests on the original
ServerSocket This particular version of the program doesn't listen for more client
connection requests. However, a modified version of the program is provided in Supporting
Multiple Clients.

After the server successfully establishes a connection with a client, it communicates with the
client using this code:

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in =
    new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));
String inputLine, outputLine;

// initiate conversation with client
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);

while ((inputLine = in.readLine()) != null) {
    outputLine = kkp.processInput(inputLine);
    out.println(outputLine);
    if (outputLine.equals("Bye."))
    break;
}

This code:

   1. Gets the socket's input and output stream and opens readers and writers on them.
   2. Initiates communication with the client by writing to the socket (shown in bold).
   3. Communicates with the client by reading from and writing to the socket (the while
      loop).

Step 1 is already familiar. Step 2 is shown in bold and is worth a few comments. The bold
statements in the code segment above initiate the conversation with the client. The code
creates a KnockKnockProtocol object-the object that keeps track of the current joke, the
current state within the joke, and so on.

After the KnockKnockProtocol is created, the code calls KnockKnockProtocol's
processInput method to get the first message that the server sends to the client. For this
example, the first thing that the server says is "Knock! Knock!" Next, the server writes the
information to the PrintWriter connected to the client socket, thereby sending the message
to the client.

Step 3 is encoded in the while loop. As long as the client and server still have something to
say to each other, the server reads from and writes to the socket, sending messages back and
forth between the client and the server.

The server initiated the conversation with a "Knock! Knock!" so afterwards the server must
wait for the client to say "Who's there?" As a result, the while loop iterates on a read from the
input stream. The readLine method waits until the client responds by writing something to its
output stream (the server's input stream). When the client responds, the server passes the
client's response to the KnockKnockProtocol object and asks the KnockKnockProtocol
object for a suitable reply. The server immediately sends the reply to the client via the output
stream connected to the socket, using a call to println. If the server's response generated from
the KnockKnockServer object is "Bye." this indicates that the client doesn't want any more
jokes and the loop quits.

The KnockKnockServer class is a well-behaved server, so the last several lines of this section
of KnockKnockServer clean up by closing all of the input and output streams, the client
socket, and the server socket:

out.close();
in.close();
clientSocket.close();
serverSocket.close();


The Knock Knock Protocol
The KnockKnockProtocol class implements the protocol that the client and server use to
communicate. This class keeps track of where the client and the server are in their
conversation and serves up the server's response to the client's statements. The
KnockKnockServer object contains the text of all the jokes and makes sure that the client
gives the proper response to the server's statements. It wouldn't do to have the client say
"Dexter who?" when the server says "Knock! Knock!"

All client/server pairs must have some protocol by which they speak to each other; otherwise,
the data that passes back and forth would be meaningless. The protocol that your own clients
and servers use depends entirely on the communication required by them to accomplish the
task.
The Knock Knock Client
The KnockKnockClient class implements the client program that speaks to the
KnockKnockServer. KnockKnockClient is based on the EchoClient program in the
previous section, Reading from and Writing to a Socket and should be somewhat familiar to
you. But we'll go over the program anyway and look at what's happening in the client in the
context of what's going on in the server.

When you start the client program, the server should already be running and listening to the
port, waiting for a client to request a connection. So, the first thing the client program does is
to open a socket that is connected to the server running on the hostname and port specified:

kkSocket = new Socket("taranis", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));

When creating its socket, KnockKnockClient uses the host name taranis, the name of a
hypothetical machine on our network. When you type in and run this program, change the
host name to the name of a machine on your network. This is the machine on which you will
run the KnockKnockServer.

The KnockKnockClient program also specifies the port number 4444 when creating its
socket. This is a remote port number--the number of a port on the server machine--and is the
port to which KnockKnockServer is listening. The client's socket is bound to any available
local port--a port on the client machine. Remember that the server gets a new socket as well.
That socket is bound to local port number 4444 on its machine. The server's socket and the
client's socket are connected.

Next comes the while loop that implements the communication between the client and the
server. The server speaks first, so the client must listen first. The client does this by reading
from the input stream attached to the socket. If the server does speak, it says "Bye." and the
client exits the loop. Otherwise, the client displays the text to the standard output and then
reads the response from the user, who types into the standard input. After the user types a
carriage return, the client sends the text to the server through the output stream attached to the
socket.

while ((fromServer = in.readLine()) != null) {
    System.out.println("Server: " + fromServer);
    if (fromServer.equals("Bye."))
        break;

     fromUser = stdIn.readLine();
     if (fromUser != null) {
         System.out.println("Client: " + fromUser);
         out.println(fromUser);
     }
}

The communication ends when the server asks if the client wishes to hear another joke, the
client says no, and the server says "Bye."
In the interest of good housekeeping, the client closes its input and output streams and the
socket:

out.close();
in.close();
stdIn.close();
kkSocket.close();


Running the Programs
You must start the server program first. To do this, run the server program using the Java
interpreter, just as you would any other Java application. Remember to run the server on the
machine that the client program specifies when it creates the socket.

Next, run the client program. Note that you can run the client on any machine on your
network; it does not have to run on the same machine as the server.

If you are too quick, you might start the client before the server has a chance to initialize
itself and begin listening on the port. If this happens, you will see a stack trace from the
client. If this happens, just restart the client.

If you forget to change the host name in the source code for the KnockKnockClient program,
you will see the following error message:

Don't know about host: taranis

To fix this, modify the KnockKnockClient program and provide a valid host name for your
network. Recompile the client program and try again.

If you try to start a second client while the first client is connected to the server, the second
client just hangs. The next section, Supporting Multiple Clients, talks about supporting
multiple clients.

When you successfully get a connection between the client and server, you will see the
following text displayed on your screen:

Server: Knock! Knock!

Now, you must respond with:

Who's there?

The client echoes what you type and sends the text to the server. The server responds with the
first line of one of the many Knock Knock jokes in its repertoire. Now your screen should
contain this (the text you typed is in bold):

Server: Knock! Knock!
Who's there?
Client: Who's there?
Server: Turnip
Now, you respond with:

Turnip who?"

Again, the client echoes what you type and sends the text to the server. The server responds
with the punch line. Now your screen should contain this:

Server: Knock! Knock!
Who's there?
Client: Who's there?
Server: Turnip
Turnip who?
Client: Turnip who?
Server: Turnip the heat, it's cold in here! Want another? (y/n)

If you want to hear another joke, type y; if not, type n. If you type y, the server begins again
with "Knock! Knock!" If you type n, the server says "Bye." thus causing both the client and
the server to exit.

If at any point you make a typing mistake, the KnockKnockServer object catches it and the
server responds with a message similar to this:

Server: You're supposed to say "Who's there?"!

The server then starts the joke over again:

Server: Try again. Knock! Knock!

Note that the KnockKnockProtocol object is particular about spelling and punctuation but
not about capitalization.

Supporting Multiple Clients
To keep the KnockKnockServer example simple, we designed it to listen for and handle a
single connection request. However, multiple client requests can come into the same port and,
consequently, into the same ServerSocket. Client connection requests are queued at the
port, so the server must accept the connections sequentially. However, the server can service
them simultaneously through the use of threads - one thread per each client connection.

The basic flow of logic in such a server is this:

while (true) {
    accept a connection;
    create a thread to deal with the client;
}

The thread reads from and writes to the client connection as necessary.


Try This:
Modify the KnockKnockServer so that it can service multiple clients at the same time. Two
classes compose our solution: KKMultiServer and KKMultiServerThread. KKMultiServer
loops forever, listening for client connection requests on a ServerSocket. When a request
comes in, KKMultiServer accepts the connection, creates a new KKMultiServerThread
object to process it, hands it the socket returned from accept, and starts the thread. Then the
server goes back to listening for connection requests. The KKMultiServerThread object
communicates to the client by reading from and writing to the socket. Run the new Knock
Knock server and then run several clients in succession.




Sending E-Mail:-
The JavaMail API is not part of core Java SE, but an optional extension. In addition, it is
required in Java Enterprise Edition. The JavaMail packages can be accessed in two ways :

        by placing j2ee.jar in the classpath
        or, by placing both mail.jar and activation.jar in the classpath

The javax.mail API uses a properties file for reading server names and related
configuration. These settings will override any system defaults. Alternatively, the
configuration can be set directly in code, using the JavaMail API.

Example

An email configuration file (to run the example, substitute valid values for the uncommented
items) :


#   Configuration file for javax.mail
#   If a value for an item is not provided, then
#   system defaults will be used. These items can
#   also be set in code.

# Host whose mail services will be used
# (Default value : localhost)
mail.host=mail.blah.com

# Return address to appear on emails
# (Default value : username@host)
mail.from=webmaster@blah.net

#   Other possible items include:
#   mail.user=
#   mail.store.protocol=
#   mail.transport.protocol=
#   mail.smtp.host=
#   mail.smtp.user=
#   mail.debug=

A class which uses this file to send an email :
import     java.util.*;
import     java.io.*;
import     javax.mail.*;
import     javax.mail.internet.*;

/**
* Simple demonstration of using the javax.mail API.
*
* Run from the command line. Please edit the implementation
* to use correct email addresses and host name.
*/
public final class Emailer {

     public static void main( String... aArguments ){
        Emailer emailer = new Emailer();
        //the domains of these email addresses should be valid,
        //or the example will fail:
        emailer.sendEmail(
           "fromblah@blah.com", "toblah@blah.com",
            "Testing 1-2-3", "blah blah blah"
        );
      }

     /**
     * Send a single email.
     */
     public void sendEmail(
        String aFromEmailAddr, String aToEmailAddr,
        String aSubject, String aBody
     ){
        //Here, no Authenticator argument is used (it is null).
        //Authenticators are used to prompt the user for user
        //name and password.
        Session session = Session.getDefaultInstance( fMailServerConfig, null
);
         MimeMessage message = new MimeMessage( session );
         try {
           //the "from" address may be set in code, or set in the
           //config file under "mail.from" ; here, the latter style is used
           //message.setFrom( new InternetAddress(aFromEmailAddr) );
           message.addRecipient(
              Message.RecipientType.TO, new InternetAddress(aToEmailAddr)
           );
           message.setSubject( aSubject );
           message.setText( aBody );
           Transport.send( message );
         }
         catch (MessagingException ex){
           System.err.println("Cannot send email. " + ex);
         }
     }

     /**
     * Allows the config to be refreshed at runtime, instead of
     * requiring a restart.
     */
     public static void refreshConfig() {
        fMailServerConfig.clear();
        fetchConfig();
     }
  // PRIVATE //

  private static Properties fMailServerConfig = new Properties();

  static {
    fetchConfig();
  }

  /**
  * Open a specific text file containing mail server
  * parameters, and populate a corresponding Properties object.
  */
  private static void fetchConfig() {
     InputStream input = null;
     try {
       //If possible, one should try to avoid hard-coding a path in this
       //manner; in a web application, one should place such a file in
       //WEB-INF, and access it using ServletContext.getResourceAsStream.
       //Another alternative is Class.getResourceAsStream.
       //This file contains the javax.mail config properties mentioned
above.
       input = new FileInputStream( "C:\\Temp\\MyMailServer.txt" );
       fMailServerConfig.load( input );
     }
     catch ( IOException ex ){
       System.err.println("Cannot open and load mail server properties
file.");
     }
     finally {
       try {
         if ( input != null ) input.close();
       }
       catch ( IOException ex ){
         System.err.println( "Cannot close mail server properties file." );
       }
     }
  }
}




Making URL Connections:-
URLConnection is a general-purpose class for accessing the attributes of a remote resource.
Once you make a connection to a remote server, you can use URLConnection to inspect the
properties of the remote object before actually transporting it locally. These attributes are
exposed by the HTTP protocol specification and, as such, only make sense for URL objects
that are using the HTTP protocol. We'll examine the most useful elements of
URLConnection here.

In the following example, we create a URLConnection using the openConnection( ) method
of a URL object and then use it to examine the document's properties and content:

// Demonstrate URLConnection.
import java.net.*;
import java.io.*;
import java.util.Date;
class UCDemo
{
public static void main(String args[]) throws Exception {
int c;
URL hp = new URL("http://www.java-samples.com/j2me/");
URLConnection hpCon = hp.openConnection();
System.out.println("Date: " + new Date(hpCon.getDate()));
System.out.println("Content-Type: " +
hpCon.getContentType());
System.out.println("Expires: " + hpCon.getExpiration());
System.out.println("Last-Modified: " +
new Date(hpCon.getLastModified()));
int len = hpCon.getContentLength();
System.out.println("Content-Length: " + len);
if (len > 0) {
System.out.println("=== Content ===");
InputStream input = hpCon.getInputStream();
int i = len;
while (((c = input.read()) != -1) && (—i > 0)) {
System.out.print((char) c);
}
input.close();
} else {
System.out.println("No Content Available");
}
}
}

The program establishes an HTTP connection to http://www.java-samples.com over port
80
and requests the document /j2me/. We then list out the header values and retrieve the content.



The URL and URLConnection classes are good enough for simple programs that want to
connect to HTTP servers to fetch content. For more complex applications, you'll probably
find that you are better off studying the specification of the HTTP protocol and implementing
your own wrappers.




Socket Programming:-
The Unix input/output (I/O) system follows a paradigm usually referred to as Open-Read-
Write-Close. Before a user process can perform I/O operations, it calls Open to specify and
obtain permissions for the file or device to be used. Once an object has been opened, the user
process makes one or more calls to Read or Write data. Read reads data from the object and
transfers it to the user process, while Write transfers data from the user process to the object.
After all transfer operations are complete, the user process calls Close to inform the operating
system that it has finished using that object.

When facilities for InterProcess Communication (IPC) and networking were added to Unix,
the idea was to make the interface to IPC similar to that of file I/O. In Unix, a process has a
set of I/O descriptors that one reads from and writes to. These descriptors may refer to files,
devices, or communication channels (sockets). The lifetime of a descriptor is made up of
three phases: creation (open socket), reading and writing (receive and send to socket), and
destruction (close socket).

The IPC interface in BSD-like versions of Unix is implemented as a layer over the network
TCP and UDP protocols. Message destinations are specified as socket addresses; each socket
address is a communication identifier that consists of a port number and an Internet address.

The IPC operations are based on socket pairs, one belonging to a communication process.
IPC is done by exchanging some data through transmitting that data in a message between a
socket in one process and another socket in another process. When messages are sent, the
messages are queued at the sending socket until the underlying network protocol has
transmitted them. When they arrive, the messages are queued at the receiving socket until the
receiving process makes the necessary calls to receive them.

TCP/IP and UDP/IP communications

There are two communication protocols that one can use for socket programming: datagram
communication and stream communication.

Datagram communication:
The datagram communication protocol, known as UDP (user datagram protocol), is a
connectionless protocol, meaning that each time you send datagrams, you also need to send
the local socket descriptor and the receiving socket's address. As you can tell, additional data
must be sent each time a communication is made.

Stream communication:
The stream communication protocol is known as TCP (transfer control protocol). Unlike
UDP, TCP is a connection-oriented protocol. In order to do communication over the TCP
protocol, a connection must first be established between the pair of sockets. While one of the
sockets listens for a connection request (server), the other asks for a connection (client). Once
two sockets have been connected, they can be used to transmit data in both (or either one of
the) directions.

   
                         Section B
DATABASE NETWORKING
    The Design of JDBC.
    The Structured Query Language,
    JDBC Installation,
    Basic JDBC Programming Concepts,
    Query Execution,
    Scrollable and Updatable Result Sets,
    Metadata,
    Row Sets,
    Transactions,
    Advanced Connection Management,
    Introduction of LDAP

DISTRIBUTED OBJECTS
    The Roles of Client and Server,
    Remote Method Invocations,
    Setup for Remote Method Invocation,
    Parameter Passing in Remote Methods Server Object Activation,
    Java IDL and CCRA,
    Remote Method Calls with SOAP
                       DATABASE NETWORKING


          The Design of JDBC:-
Database programming has traditionally been a technological Tower of Babel. We are faced
with dozens of available database products, and each one talks to our applications in its own
private language. If your application needs to talk to a new database engine, you have to
teach it (and yourself) a new language. As Java programmers, however, we should not be
worrying about such translation issues. Java is supposed to bring us the ability to "write once,
compile once, and run anywhere," so it should bring it to us with database programming as
well.

Java's JDBC API gives us a shared language through which our applications can talk to
database engines. Following in the tradition of its other multi-platform APIs such as the
AWT, JDBC provides us with a set of interfaces that create a common point at which
database applications and database engines can meet. In this chapter, we will discuss the
basic interfaces that JDBC provides.

What Is JDBC?
Working with leaders in the database field, JavaSoft developed a single API for database
access--JDBC. As part of this process, they kept three main goals in mind:

      JDBC should be an SQL-level API.
      JDBC should capitalize on the experience of existing database APIs.
      JDBC should be simple.

An SQL-level API means that JDBC allows us to construct SQL statements and embed them
inside Java API calls. In short, you are basically using SQL. But JDBC lets you smoothly
translate between the world of the database and the world of the Java application. Your
results from the database, for instance, are returned as Java variables, and access problems
get thrown as exceptions. Later on in the book, we go a step further and talk about how we
can completely hide the existence of the database from a Java application using a database
class library.

Because of the confusion caused by the proliferation of proprietary database access APIs, the
idea of a universal database access API to solve this problem is not a new one. In fact,
JavaSoft drew upon the successful aspects of one such API, Open DataBase Connectivity
(ODBC). ODBC was developed to create a single standard for database access in the
Windows environment. Although the industry has accepted ODBC as the primary means of
talking to databases in Windows, it does not translate well into the Java world. First of all,
ODBC is a C API that requires intermediate APIs for other languages. But even for C
developers, ODBC has suffered from an overly complex design that has made its transition
outside of the controlled Windows environment a failure. ODBC's complexity arises from the
fact that complex, uncommon tasks are wrapped up in the API with its simpler and more
common functionality. In other words, in order for you to understand a little of ODBC, you
have to understand a lot.
In addition to ODBC, JDBC is heavily influenced by existing database programming APIs
such as X/OPEN SQL Call Level Interface. JavaSoft wanted to re-use the key abstractions
from these APIs, which would ease acceptance by database vendors and capitalize on the
existing knowledge capital of ODBC and SQL CLI developers. In addition, JavaSoft also
realized that deriving an API from existing ones can provide quick development of solutions
for database engines that support the old protocols. Specifically, JavaSoft worked in parallel
with Intersolv to create an ODBC bridge that maps JDBC calls to ODBC calls, thus giving
Java applications access to any database management system (DBMS) that supports ODBC.

JDBC attempts to remain as simple as possible while providing developers with maximum
flexibility. A key criterion employed by JavaSoft is simply asking whether database access
applications read well. The simple and common tasks use simple interfaces, while more
uncommon or bizarre tasks are enabled through extra interfaces. For example, three interfaces
handle a vast majority of database access. JDBC nevertheless provides several other
interfaces for handling more complex and unusual tasks.

The Structure of JDBC

JDBC accomplishes its goals through a set of Java interfaces, each implemented differently
by individual vendors. The set of classes that implement the JDBC interfaces for a particular
database engine is called a JDBC driver. In building a database application, you do not have
to think about the implementation of these underlying classes at all; the whole point of JDBC
is to hide the specifics of each database and let you worry about just your application. Figure
4-1 shows the JDBC classes and interfaces.

Figure 4-1. The classes and interfaces of java.sql, the JDBC API package




If you think about a database query for any database engine, it requires you to connect to the
database, issue your SELECT statement, and process the result set. In Example 4-1, we have
the full code listing for a simple SELECT application from the Imaginary JDBC Driver for
mSQL.[1] I wrote this driver for the Center for Imaginary Environments
(http://www.imaginary.com), which is a non-commercial organization that promotes the
development of virtual environment technologies like muds. This application is a single class
that gets all of the rows from a table in an mSQL database located on my Sun box. First, it
connects to the database by getting a database connection under my user id, borg, from the
JDBC DriverManager class. It uses that database connection to create a Statement object
that performs the SELECT query. A ResultSet object then provides the application with the
key and val fields from the t_test table.

Example 4-1: A Simple SELECT Application from the Imaginary JDBC
Implementation for mSQL

import java.sql.*;

public class SelectApp {
  public static void main(String args[]) {
    String url = "jdbc:msql://athens.imaginary.com:4333/db_web";

        try {
          Class.forName("imaginary.sql.iMsqlDriver");
        }
        catch( Exception e ) {
          System.out.println("Failed to load mSQL driver.");
          return;
        }
        try {
          Connection con = DriverManager.getConnection(url, "borg", "");
          Statement select = con.createStatement();
          ResultSet result = select.executeQuery
                               ("SELECT key, val FROM t_test");

         System.out.println("Got results:");
         while(result.next()) { // process results one row at a time
           int key = result.getInt(1);
           String val = result.getString(2);

            System.out.println("key = " + key);
            System.out.println("val = " + val);
         }
         select.close();
         con.close();
        }
        catch( Exception e ) {
          e.printStackTrace();
        }
    }
}

If you already have Java experience, then you should be able to understand the flow of the
code in Example 4-1 without knowing any JDBC. There are no references to specific
database engine classes. Instead, the code simply uses JDBC interfaces to provide a facade
for the DBMS-specific implementation. The JDBC implementation, in turn, performs the
actual database access somewhere behind the scenes.

In this simple application, the SelectApp class asks the JDBC DriverManager to hand it the
proper database implementation based on a database URL. The database URL looks similar
to other Internet URLs. The actual content of the URL is loosely specified as
jdbc:subprotocol:subname. The subprotocol identifies which driver to use, and the subname
provides the driver with any required connection information. For the Imaginary JDBC
Implementation for mSQL that I used in testing the above example, the URL is
jdbc:msql://athens.imaginary.com:4333/db_web. In other words, this URL says to use the
mSQL JDBC driver to connect to the database db_web on the server running at port 4333 on
athens.imaginary.com. Each URL, however, is specific to the JDBC implementation being
sought, and so I can't say anything more explicit about it. Whatever its format, the primary
function of a database URL is to uniquely identify the implementation needed by the
application and pass that implementation any information it needs in order to connect to the
proper database.

Databases and Drivers

In putting together the examples in this book, I used both an mSQL database for the simple
Chapter 4 examples and an Oracle database for the more complex examples of Chapter 5. If
you do not have a corporate pocketbook to back up your database purchase, mSQL is
probably the most feasible solution. You should keep in mind, however, that mSQL does not
allow you to abort transactions and does not support the stored procedures used in Chapter 5.
Whatever your database choice, you must set up your database engine, create a database, and
create the tables shown in the Chapter 3 data model before you can begin writing JDBC code.

Once your database engine is installed and your database is all set up, you will need a JDBC
driver for that database engine. You can find an mSQL JDBC driver at
http://www.imaginary.com/Java. The more commercial database engines like Oracle have
commercial JDBC drivers. Most of them, however, allow you to have a free trial period for
experimenting with the driver. Follow the install instructions for the driver you choose, and
remember that some JDBC drivers require to you install native code on client machines. To
help you understand what different drivers require, JavaSoft has defined the following driver
categorization system:

type 1
         These drivers use a bridging technology to access a database. The JDBC-ODBC
         bridge that comes with the JDK 1.1 is a good example of this kind of driver. It
         provides a gateway to the ODBC API. Implementations of that API in turn do the
         actual database access. Bridge solutions generally require software to be installed on
         client systems, meaning that they are not good solutions for applications that do not
         allow you to install software on the client.
type 2
         The type 2 drivers are native API drivers. This means that the driver contains Java
         code that calls native C or C++ methods provided by the individual database vendors
         that perform the database access. Again, this solution requires software on the client
         system.
type 3
         Type 3 drivers provide a client with a generic network API that is then translated into
         database specific access at the server level. In other words, the JDBC driver on the
         client uses sockets to call a middleware application on the server that translates the
         client requests into an API specific to the desired driver. As it turns out, this kind of
         driver is extremely flexible since it requires no code installed on the client and a
         single driver can actually provide access to multiple databases.
type 4
         Using network protocols built into the database engine, type 4 drivers talk directly to
         the database using Java sockets. This is the most direct pure Java solution. In nearly
         every case, this type of driver will come only from the database vendor.
Table 4-1 lists the driver vendors that were public at the time of this book's publication. See
http://splash.javasoft.com/jdbc/jdbc.vendors.html for a current list of JDBC vendors.

                     Table 4-1: A List of JDBC Driver Vendors
        Vendor         Type                     Supported Databases
Agave Software Design 3       Oracle, Sybase, Informix, ODBC supported databases
Asgard Software             3      Unisys A series DMSII database
Borland                     4      InterBase 4.0
Caribou Lake Software       3      CA-Ingres
Center for Imaginary
                            4      mSQL
Environments
Connect Software            4      Sybase, MS SQL Server
DataRamp                    3      ODBC supported databases
IBM                         2/3    IBM DB2 Version 2
                                   Oracle, Sybase, MS SQL Server, MS Access, Informix,
IDS Software                3
                                   Watcom, ODBC supported databases
InterSoft                   3      Essentia
Intersolv                   2      Oracle, Sybase
JavaSoft                    1      ODBC supported databases
OpenLink                    3      CA-Ingres, Postgres95, Progress, Unify
                                   SAS, and via SAS/ACCESS, Oracle, Informix, Ingres, and
SAS                         4
                                   ADABAS
SCO                         3      Informix, Oracle, Ingres, Sybase, Interbase
StormCloud Development 3           ODBC supported databases
                                   Sybase SQL Server, SQL Anywhere, Sybase IQ,
Sybase                      3/4
                                   Replication Server
                                   Oracle, Sybase, MS SQL Server, MS Access, Watcom,
Symantec                    3
                                   ODBC supported databases
Visigenic                   3      ODBC supported databases
                                   Oracle, Sybase, MS SQL Server/ODBC supported
WebLogic                    2/3
                                   databases

Alternatives to JDBC

Without JDBC, only disparate, proprietary database access solutions exist. These proprietary
solutions force the developer to build a layer of abstraction on top of them in order to create
database independent code. Only after that abstraction layer is complete can the developer
move to actually writing the application. In addition, the experience you have with that
abstraction layer does not translate immediately to other projects or other employers who are
almost certainly using their own abstraction layers to provide access to a variety of database
engines.
Of course, the ODBC specification exists to provide this universal abstraction layer for
languages like C and C++ as well as popular development tools such as Delphi,
PowerBuilder, and VisualBasic. Unfortunately, ODBC does not enjoy the platform
independence of Java. Using the JDBC interface design, however, your server application can
pick the database at runtime based on which client is connecting. The ATM front-end of the
banking application, for example, could have some legacy data stored in an Oracle system
that is not yet converted to the Informix system against which the rest of the application is
running. You write the application without writing special access code for the legacy data.
The ATM client just passes the Oracle URL when requesting the connect. Once its data has
been converted to Informix, all you have to do to switch the application to the new database
is tell the ATM machine about the new database URL. No new code needs to be written for
the migration.

Connecting to the Database
Now I am going to dive into the details about JDBC calls and how to use them. Any JDBC
application we write needs to be able to run from start to finish without ever referencing a
specific JDBC implementation. Figure 4-2 shows how an application uses JDBC to talk to
one or more databases without knowing any of the details concerning the driver
implementation for that database. An application uses JDBC as an interface through which it
passes all of its databases requests.

   Figure 4-2. JDBC shields an application from the specifics of individual database
                                  implementations




When you write a Java database applet or application, the only driver-specific information
JDBC requires from you is the database URL. You can even build your application so that it
derives the URL at runtime--based on user input or applet parameters.

Using the database URL, a user name, and password, your application will first requests a
java.sql.Connection implementation from the DriverManager. The DriverManager in
turn will search through all of the known java.sql.Driver implementations for one that
will connect with the URL you provided. If it exhausts all of the implementations without
finding a match, it throws an exception back to your application.

Once a Driver recognizes your URL, it creates a database connection using the user name
and password you specified. It then provides the DriverManager with a
java.sql.Connection implementation representing that database connection. The
DriverManager then passes that Connection object back to the application. In your code, the
entire database connection process is handled by this one-liner:

Connection con = DriverManager.getConnection(url, uid, password);

Of course, you are probably wondering just how the JDBC DriverManager learns about a
new driver implementation. The DriverManager actually keeps a list of classes that
implement the java.sql.Driver interface. Somehow, somewhere, your application needs to
load the Driver implementations for any potential database drivers it might require. JDBC
requires a Driver class to register itself with the DriverManager when it gets loaded. The
very act of loading a Driver class thus enters it in the DriverManager's list. Your only task
is thus to determine the somehow and somewhere of loading those Driver implementations.
You have several alternatives:

Explicitly call new to load your driver's implementation of Driver
       In other words, you hard code the loading of a Driver implementation in your
       application. This alternative is the least desirable since it requires a rewrite and
       recompile if your database or database driver changes.
Use the jdbc.drivers property
       The DriverManager will load all classes listed in this property automatically. This
       alternative works well for applications with a command-line interface, but might not
       be so useful in GUI applications and applets. This is because you can specify
       properties at the command line or in environment variables. While environment
       variables do work for GUI applications, you cannot rely on them in Java applets.
Load the class using Class.forName("DriverImplementationClass");
       You can use this Java mechanism for loading classes dynamically based on a String
       with the class name. This static method in the Class class returns the Java class
       represented by String you pass. A side-effect of this behavior is that the static
       constructor in that class will be executed. JDBC requires that the static constructor for
       a Driver implementation load an instance of the Driver. As I said earlier, when you
       load a Driver, it registers itself with the DriverManager.

I use the third alternative almost exclusively in the examples in this book since it requires no
hard-coded class names and runs well in all Java environments.

The JDBC Classes for Creating a Connection

As you can see from the process flow above, JDBC uses one class
(java.sql.DriverManager) and two interfaces (java.sql.Driver and
java.sql.Connection) for connecting to a database.

java.sql.Driver
       Unless you are writing your own custom JDBC implementation, you should never
       have to deal with this class from your application. It simply gives JDBC a launching
       point for database connectivity by responding to DriverManager connection requests
       and providing information about the implementation in question.
java.sql.DriverManager
       Unlike most other parts of JDBC, DriverManager is a class instead of an interface. Its
       main responsibility is to maintain a list of Driver implementations and present an
       application with one that matches a requested URL. The DriverManager provides
       registerDriver() and deregisterDriver() methods, which allow a Driver
       implementation to register itself with the DriverManager or remove itself from that
       list. You can get an enumeration of registered drivers through the getDrivers()
       method.
java.sql.Connection
      The Connection class represents a single logical database transaction. In other words,
      you use the Connection class for sending a series of SQL statements to the database
       and managing the committing or aborting of those statements.

Example 4-2 puts the process of connecting to the database into a more concrete format.

Example 4-2: A Simple Database Connection

package example.sql;

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


/**
 * The SimpleConnection class is a command line application that accepts
 * the following command line:
 * java SimpleConnection DRIVER URL UID PASSWORD
 * If the URL fits the specified driver, it will then load the driver and
 * get a connection.
 */
public class SimpleConnection {
  static public void main(String args[]) {
    Connection connection = null;

    // Process the command line
    if( args.length != 4 ) {
      System.out.println("Syntax: java SimpleConnection " +
                         "DRIVER URL UID PASSWORD");
      return;
    }
    try { // load the driver
      Class.forName(args[0]);


    }
    catch( Exception e ) { // problem loading driver, class not exist?
      e.printStackTrace();
      return;
    }
    try {
      connection = DriverManager.getConnection(args[1], args[2], args[3]);
      System.out.println("Connection successful!");
      // Do whatever queries or updates you want here!!!
    }
     catch( SQLException e ) {
       e.printStackTrace();
     }
     finally {
         try {
             connection.close();
         }
         catch( SQLException e ) {
             e.printStackTrace();
         }
     }
}

In connecting to the database, this example catches an SQLException. This is a sort of catch-
all exception for database errors. Just about any time something goes wrong between JDBC
and the database, JDBC throws an SQLException. In addition to the information you
commonly find in Java exceptions, SQLException also provides database specific error
information, such as the SQLState value and vendor error code. JDBC SQLExceptions may
be chained together so that you can find out everything that went wrong with a catastrophic
database call.

Basic Database Access
Now that you are connected to the database, you can begin making updates and queries. The
most basic kind of database access involves writing JDBC code where you know ahead of
time whether the statements you are sending are updates (INSERT, UPDATE, or DELETE)
or queries (SELECT). In the next chapter, we will discuss more complex database access that
allows you to execute statements of unknown types.

Basic database access starts with the Connection object you created in the previous section.
When this object first gets created, it is simply a direct link to the database. You use a
Connection object to generate implementations of java.sql.Statement tied to the same
database transaction. After you have used one or more Statement objects generated by your
Connection, you can use it to commit or rollback the Statement objects associated with that
Connection.

A Statement is very much what its name implies--an SQL statement. Once you get a
Statement object from a Connection, you have what amounts to a blank check that you can
write against the transaction represented by that Connection. You do not actually assign
SQL to the Statement until you are ready to send the SQL to the database.

This is where it becomes important to know what type of SQL you are sending to the
database, because JDBC uses a different method for sending queries than for sending
updates. The key difference is the fact that the method for queries returns an instance of
java.sql.ResultSet while the method for non-queries returns an integer. A ResultSet
provides you with access to the data retrieved by a query.

Basic JDBC Database Access Classes
java.sql.Statement
       The Statement class is the most basic of three JDBC classes representing SQL
       statements. It performs all of the basic SQL statements we have discussed so far. In
       general, a simple database transaction uses only one of the three statement execution
       methods in the Statement class. The first such method, executeQuery(), takes an
       SQL String as an argument and returns a ResultSet object. This method should be
       used for any SQL calls that expect to return data from the database. Update
       statements, on the other hand, are executed using the executeUpdate() method. This
       method returns the number of affected rows.
       Finally, the Statement class provides an execute() method for situations in which
       you do not know whether the SQL being executed is a query or update. This usually
       happens when the application is executing dynamically created SQL statements. If the
       statement returns a row from the database, the method returns true. Otherwise it
       returns false. The application can then use the getResultSet() method to get the
       returned row.
java.sql.ResultSet
      A ResultSet is    a row of data returned by a database query. The class simply provides
       a series of methods for retrieving columns from the results of a database query. The
       methods for getting a column all take the form:

type get type(int | String)

       where the argument represents either the column number or column name desired. A
       nice side effect of this design is that you can store values in the database as one type
       and retrieve them as a completely different type. For example, if you need a Date
       from the database as a String, you can get it as a String by calling
       result_set.getString(1) instead of calling result_set.getDate(1).
       Because the ResultSet class handles only a single row from the database at any
       given time, the class provides the next() method for making it reference the next row
       of a result set. If next() returns true, you have another row to process and any
       subsequent calls you make to the ResultSet object will be in reference to that next
       row. If there are no rows left, it returns false.
       Please note that ResultSet objects allow only one-way navigation through rows from
       a query--there is no previous() counterpart to the next() method. JavaSoft is
       considering the addition of a RowSet class for Java 1.2 that will allow you to scroll
       through result sets in a manner similar to database cursors.

Clean Up

In the examples provided so far, you may have noticed many of the objects being closed
through a close() method. The Connection, Statement, and ResultSet classes all have
close(). A given JDBC implementation may or may not require you to close these objects
before reusing. But some might, since they likely are holding precious database resources. It
is therefore always a good idea to close any instance of the above objects when you are done
with them. If you do manage to close a Connection before committing with auto-commit off,
any uncommitted transactions will be lost.

Modifying the Database
In Example 4-1, we used JDBC to perform a simple SELECT query. Of course, we cannot
really retrieve data from the database before we have put it there. Example 4-3 shows the
simple UpdateApp class supplied with the Imaginary JDBC Implementation for mSQL.

Example 4-3: UpdateApp from the Imaginary JDBC Implementation for mSQL

import java.sql.*;

class UpdateApp {
  public static void main(String args[]) {
    Connection connection = null;

        if( args.length != 2 ) {
          System.out.println("Syntax: <java UpdateApp [number] [string]>");
          return;
        }
        try {
          Class.forName("imaginary.sql.iMsqlDriver");
          String url = "jdbc:msql://athens.imaginary.com:4333/Testdb";
          con = DriverManager.getConnection(url, "borg", "");
          Statement s = con.createStatement();
          String test_id = args[0];
          String test_val = args[1];
          int update_count =
            s.executeUpdate("INSERT INTO t_test (test_id, test_val) " +
                             "VALUES(" + test_id + ", '" + test_val + "')");

          System.out.println(update_count + " rows inserted.");
          s.close();
        }
        catch( Exception e ) {
          e.printStackTrace();
        }
        finally {
           try { con.close(); }
           catch( SQLException e ) { e.printStackTrace(); }
        }
    }
}

Again, making a database call is nothing more than creating a Statement and passing it SQL
via one of its execute methods. Unlike executeQuery(), however, executeUpdate() does
not return a ResultSet (you should not be expecting any results). Instead, it returns the
number of rows affected by the UPDATE, INSERT, or DELETE.

By default, JDBC commits each SQL statement as it is sent to the database; this is called
autocommit. However, for more robust error handling, you can set up a Connection object so
it issues a series of changes that have no effect on the database until you expressly send a
commit. Each Connection is separate, and a commit on one has no effect on the statements
on the other. The Connection class provides the setAutoCommit() method so you can turn
autocommit off. Example 4-4 shows a simple application that turns autocommit off and
commits two statements together or not at all.

Example 4-4: UpdateLogic Application That Commits Two Updates Together

import java.sql.*;
class UpdateLogic {
  public static void main(String args[]) {
    Connection connection = null;

        if( args.length != 2 ) {
          System.out.println("Syntax: <java UpdateLogic [number] [string]>");
          return;
        }
        try {
          Class.forName("imaginary.sql.iMsqlDriver");
          String url = "jdbc:msql://athens.imaginary.com:4333/db_test";
          Statement s;

         con = DriverManager.getConnection(url, "borg", "");
         con.setAutoCommit(false);     // make sure auto commit is off!
         s = con.createStatement();    // create the first statement
         s.executeUpdate("INSERT INTO t_test (test_id, test_val) " +
                         "VALUES(" + args[0] + ", '" + args[1] + "')");
         s.close();                    // close the first statement
         s = con.createStatement();    // create the second statement
         s.executeUpdate("INSERT into t_test_desc (test_id, test_desc) " +
                         "VALUES(" + args[0] +
                         ", `This describes the test.')");
         con.commit();                 // commit the two statements
         System.out.println("Insert succeeded.");
         s.close();                    // close the second statement
        }
        catch( SQLException e ) {
          if( con != null ) {
            try { con.rollback(); }        // rollback on error
            catch( SQLException e ) { }
          }
          e.printStackTrace();
        }
        finally {
          try { con.close(); }
          catch( SQLException e ) { e.printStackTrace(); }
        }
    }
}


The JDBC Support Classes
JDBC provides a handful of other classes and interfaces that support JDBC's core
functionality. Many of them are more SQL-friendly extensions of java.util classes like
java.sql.Date and java.sql.Numeric. Others are exception classes that get thrown by
JDBC calls.

java.sql.Types

The Types class provides constants that identify SQL data types. Each constant that
represents an SQL data type that is mapped to an integer is defined by the XOPEN SQL
specification. You will see this class used extensively in the next chapter.

java.sql.SQLException
The SQLException class extends the general java.lang.Exception class that provides extra
information about a database error. The information provided by a SQLException includes:

      The SQLState string describing the error according to the XOPEN SQLState
       conventions. The different values of this string are defined in the XOPEN SQL
       specification.
      The database-specific vendor error code. This code is usually some number that you
       have to look up in the obscure reference section of your database's documentation.
       Fortunately, the error should be sufficiently described through the Java Exception
       class's getMessage() method.
      A chain of exceptions leading up to this one. This is one of the niftier features of this
       class. Specifically, if you get several errors during the execution of a transaction, you
       can chain them all together in this class. This is frequently useful when you have
       exceptions that you want to let the user to know about, but you do not want to stop
       processing.

       try { Connection connection = DriverManager.getConnection(url, uid,
       pass); } catch( SQLException e ) { e.printStackTrace(); while( (e =
       e.getNextException()) != null ) { // while more exceptions
       e.printStackTrace(); } }

java.sql.SQLWarning and java.sql.DataTruncation

Depending on the driver you are using, non-fatal errors might occur that should not halt
application processing. JDBC provides an extension to the SQLException class called
SQLWarning. When a JDBC object--like a ResultSet--encounters a warning situation
internally, it creates an SQLWarning object and adds it to a list of warnings that it keeps. At
any point, you can get the warnings for any JDBC object by repeatedly calling the
getWarnings() method until it returns null.

The DataTruncation class is a special kind of warning that a JDBC implementation throws
when JDBC unexpectedly truncates a data value. A DataTruncation object is chained as a
warning on a read operation and thrown as an exception on a write.

java.sql.Date, java.sql.Time, and java.sql.Timestamp

Portable date handling among database engines can be very complex--each relational
database management system (RDBMS) seems to have its own unique way of representing
date information. These three classes all extend the functionality of other Java objects to
provide a portable representation of their SQL counterparts. The Date and Time classes
represent different levels of granularity as well as different means of expressing information
already found in the java.util.Date class. The java.sql.Date class, for example,
provides methods to express just the date, month, and year, while the Time class works in
terms of hours, minutes, and seconds. And finally the Timestamp class takes the
java.util.Date class down to nanosecond granularity.

java.sql.DriverPropertyInfo

I can almost guarantee that you will never use this class. It is designed for Rapid Application
Development (RAD) tools like Symantec VisualCafe and Borland JBuilder. In order to
provide a graphical user interface for rapid prototyping, these tools need to know what
properties are required by a given JDBC implementation in order to connect to the database.
Most drivers, for example, need to know the user name and password of the user connecting
to the database. That and anything else the driver needs in order to connect to the database
will be returned as an array of DriverPropertyInfo objects from the java.sql. Driver
getPropertyInfo() method. Development tools can call this method to find out what
information they should prompt the user for before connecting to the database.



            1. mSQL stands for Mini-SQL. It is a small database that supports a subset of
               SQL and is ideal for systems that need a database that can operate with few
               system resources. You can get more information on it at http://Hughes.com.au.


The Structured Query Language:-
Structured Query Language in Java (SQLJ) is a set of programming extensions that enable a
programmer, using the Java programming language, to embed statements that provide SQL
(Structured Query Language) database requests.

Advantages of developing applications with SQLJ include improved performance and a
shorter, more efficient development cycle:

       You improve performance by using static SQL statements.
       You reduce the development cycle because:
           o You write less code with the simpler SQLJ syntax, which reduces the number
               of lines of code required to execute statements, and to set and retrieve
               parameters.
           o You detect programming errors earlier in the development phase with the
               onlinecheck function, which performs data type and schema validation.
               Activate this function by running it as an option with the db2sqljcustomize
               command. See the DB2 documentation for a complete description of the SQLJ
               customize command.




The Structured Query Language (SQL) is the language of databases. All modern relational databases,
including Access, FileMaker Pro, Microsoft SQL Server and Oracle use SQL as their basic building
block. In fact, it’s often the only way that you can truly interact with the database itself. All of the
fancy graphical user interfaces that provide data entry and manipulation functionality are nothing
more than SQL translators. They take the actions you perform graphically and convert them to SQL
commands understood by the database.

SQL is Similar to English

At this point, you might be thinking that you’re not a programmer and learning a programming
language is certainly not up your alley. Fortunately, at its core, SQL is a simple language. It has a
limited number of commands and those commands are very readable and are almost structured like
English sentences.

Introducing Databases

Before we get started, it’s important that you have a basic understanding of how databases work. If
you’re comfortable with terms like table, relation and query, feel free to plow right ahead! If not,
you may wish to read the article Database Fundamentals before moving on.

Let’s look at an example. Suppose you have a simple database designed to keep the inventory for a
convenience store. One of the tables in your database might contain the prices of the items on your
shelves indexed by unique stock numbers that identify each item. You’d probably give that table a
simple name like “Prices.” If you were considering removing items from your store that were priced
over $5, you might want to retrieve this information from your database.

Your First SQL Query

Before we get into the SQL statement required to retrieve this information, let’s try phrasing our
question in plain English. We want to “select all stock numbers from the prices table where the price
is over $5.” That’s a pretty simple request when expressed in plain English, and it’s almost as simple
in SQL! Here’s the corresponding SQL statement:

SELECT StockNumber
FROM Prices
WHERE Price > 5

It’s as simple as that! If you read the statement above out loud, you’ll find that it’s extremely similar
to the English question we posed in the last paragraph.

Interpreting SQL Statements

Now let’s try another example. This time, however, we’ll do it backwards. First, I’ll provide you with
the SQL statement and let’s see if you can explain it in plain English:

SELECT Price
FROM Prices
WHERE StockNumber = 3006

So, what do you think this statement does? That’s right, it retrieves the price from the database for
item 3006.

There’s one simple lesson you should take away from our discussion at this point: SQL is like English.
Don’t worry about how you construct SQL statements; we’ll get to that in the rest of our series. Just
realize that SQL isn’t as intimidating as it may first appear.

The Structured Query Language (SQL) comprises one of the fundamental building blocks of
modern database architecture. SQL defines the methods used to create and manipulate
relational databases on all major platforms. At first glance, the language may seem
intimidating and complex but it's really not all that bad. In a series of articles over the next
few weeks we'll explore the inner workings of SQL together. By the time we're through,
you'll have the fundamental knowledge you need to go out there and start working with
databases!

This week, our first article in the SQL series provides an introduction to the basic concepts
behind SQL and we'll take a brief look at some of the main commands used to create and
modify databases. Throughout this article, please keep our goal in mind: we're trying to get
the "big picture" of SQL -- not a mastery of the individual commands. We'll provide a few
examples for illustrative purposes and explain the theory behind them, but don't feel
frustrated if you can't write your own SQL commands after reading this article. We'll cover
each of the major commands in detail in future weekly installments. If you'd like a reminder
in your e-mail inbox each week when the next article is posted, please take a moment and
subscribe to our newsletter.

By the way, the correct pronunciation of SQL is a contentious issue within the database
community. In their SQL standard, the American National Standards Institute declared that
the official pronunciation is "es queue el." However, many database professionals have taken
to the slang pronunciation "sequel." The choice is yours.

SQL comes in many flavors. Oracle databases utilize their proprietary PL/SQL. Microsoft
SQL Server makes use of Transact-SQL. However, all of these variations are based upon the
industry standard ANSI SQL. In our tutorial series, we'll stick to ANSI-compliant SQL
commands that will work on any modern relational database system.

SQL commands can be divided into two main sublanguages. The Data Definition Language
(DDL) contains the commands used to create and destroy databases and database objects.
After the database structure is defined with DDL, database administrators and users can
utilize the Data Manipulation Language to insert, retrieve and modify the data contained
within it. In the next two sections of this article, we'll explore DDL and DML in further
detail. In future articles we'll take an in-depth look at specific SQL commands.

Now, let's take a look at the Data Definition Language. Read on!




JDBC Installation:-

DBC Installation
24.4.1. Obtaining EnterpriseDB JDBC Connector
EnterpriseDB JDBC Connector         is shipped with our installer.

24.4.2. Installing EnterpriseDB JDBC Connector
This step assumes that you have already setup Java on your system, if you have not already
done so please read Section 24.4.3.

If you manually want to install with the jar file for the driver, then you can do so in the
following ways:

      Copy the "edb-jdbc14.jar" file to any directory on your computer that is listed in your
       classpath.
      Edit the CLASSPATH environment variable and append the full path to the "edb-
       jdbc14.jar" file.
      Copy the "edb-jdbc14.jar" file to your $JAVA_HOME/jre/lib/ext directory.

24.4.3. Installing Java
This section walks you through the installation of Java in case you don't already have it setup
on your system. The setup can be downloaded at Sun's website. Please visit
http://java.sun.com/j2se/1.4.2/download.html for details.

For Windows you can download the offline executable installer or an online version installer.
If you have downloaded the offline version of the installer, you will double click on the file
once it has finished downloading in order to begin the installation. After a few simple steps
you should have Java installed on your system. Once the installation is done, you need to add
the

/bin

directory of your Java installation to the PATH environment variable in order to have access to
all the Java tools located under this directory from the Windows command prompt.

In the case of Linux, you will most likely find both an RPM and a self-extracting BIN file. If
you download the RPM file, it will include a BIN extension, which you will need to remove
manually on your own. Once this is done, install the RPM using the

rpm -ivh

command. In case you downloaded the BIN file, you will need to give the BIN execution
permissions via a

chmod a+x

command. Once the permissions are in place, simply execute the file and install Java.




Using EnterpriseDB JDBC Connector with
Java applications
Now that we have all our requirements in place, we can start writing Java code to access an
EnterpriseDB database using EnterpriseDB JDBC Connector.

24.5.1. HelloWorld Test Program
Lets start off with a traditional Hello World application. The code in the following listing
creates a Java application that pulls data from a EnterpriseDB database.


import java.sql.*;

public class HelloWorld
{
  public static void main(String[] args)
  {
    try
    {
          Class.forName("com.edb.Driver");
          Connection con =
DriverManager.getConnection("jdbc:edb://localhost:5444/edb",
          "enterprisedb","enterprisedb");
          Statement statement = con.createStatement();
          ResultSet rs = statement.executeQuery("SELECT * FROM emp");

            while(rs.next()) {
               System.out.println(rs.getString(1));
            }

            rs.close();
            statement.close();
            con.close();
            System.out.println("Command successfully executed");
        }

        catch(ClassNotFoundException e)
        {
              System.out.println("Class Not Found : " + e.getMessage());
        }

        catch(SQLException exp) {
           System.out.println("SQL Exception: " + exp.getMessage());
           System.out.println("SQL State: " + exp.getSQLState());
           System.out.println("Vendor Error: " + exp.getErrorCode());
        }
    }
}



24.5.2. Loading EnterpriseDB JDBC Connector
The process of loading and instantiating the EnterpriseDB JDBC Connector begins with the

Class.forName

method. The forName method of the Class object is designed for dynamically loading Java
classes at runtime. Due to this statement the JVM (Java Virtual Machine) attempts to find the
class passed to this method as a parameter using the current system path as well as any
additional paths defined when the JVM is executed. In our case this is the Driver class in the

com.edb

package. We explained the placement of the EnterpriseDB JDBC Connector jar file in the
system CLASSPATH in Section 24.4.2 so that this class can be found by the JVM. Once the file
is found, the Driver will register itself with a static class called DriverManager, which is
responsible for managing all the JDBC drivers installed on the current system.

In case the JVM is unable to locate the driver, it outputs a message to the console and exits
the application. The DriverManager is designed to handle multiple JDBC driver objects as
long as they register with a class, meaning that you can write a Java application that connects
with more than one database system via JDBC. Please keep in mind that no connection is
made with the database at this time and point, and that the driver is simply loaded.

24.5.3. Connecting to the Database
Once the driver has been loaded and registered with the JVM, we attempt to build a
connection to the database. The code responsible for this action is:

         Connection con = DriverManager.getConnection
("jdbc:edb://localhost:5444/edb",
         "enterprisedb","enterprisedb");


The DriverManager class has a static method called getConnection which is responsible for
creating a connection to the database. Once the getConnection method is called, the
DriverManager needs to decide which JDBC driver to use for connecting to the database.

This decision is taken based on the parameter passed to the getConnection method which
expects a connection string in the form of a URL (Uniform Resource Locator) in place of the
first parameter. A URL is used because it provides a common way of locating resources
found on the Internet. A URL takes the following general format:

<protocol>:<subprotocol>:<subname>

In the world of JDBC, the protocol is defined as jdbc, and the subprotocol is typically the
name of the driver this particular connecting URL needs to use. In the case of EnterpriseDB,
this subprotocol is defined as edb.

Hence our URL takes one of the following forms:

      jdbc:edb:// (database)
      jdbc:edb:// (host) / (database)
      jdbc:edb:// (host) : (port) / (database)

Table 24-1 depicts the various connection parameters:

Table 24-1. Connection Parameters
 Name                                         Description
host       The host name of the server. Defaults to localhost.

port
           The port number the server is listening on. Defaults to the EnterpriseDB standard
           port number (5444).
database   The database name.

To connect, you need to get a Connection instance from JDBC. To do this, you use the

DriverManager.getConnection()

method as follows:

Connection db = DriverManager.getConnection(url, username, password);


24.5.4. Additional Connection Properties
In addition to the standard connection parameters the driver supports a number of additional
properties which can be used to specify additional driver behavior specific to EnterpriseDB.
These properties may be specified in either the connection URL or an additional Properties
object parameter to:

DriverManager.getConnection()

The following examples illustrate the use of both methods to establish a SSL connection.

String url = "jdbc:edb://localhost:5444/edb";
Properties props = new Properties();
props.setProperty("user","enterprisedb");
props.setProperty("password","enterprisedb");
props.setProperty("ssl","true");
Connection conn = DriverManager.getConnection(url, props);

Table 24-2 depicts the various connection parameters:

Table 24-2. Additional Connection Properties

                     Data
       Name                                             Description
                     Type
user
                              The database user on whose behalf the connection is being
                     String
                              made.
password             String The database user's password.
                              Set the amount of logging information printed to the
                              DriverManager's current value for LogStream or LogWriter. It
                              currently supports values of
loglevel             int
                                 1. com.edb.Driver.DEBUG
                                 2. com.edb.Driver.INFO
                      Data
      Name                                                Description
                      Type
                              INFO  will log very little information while DEBUG will produce
                              significant detail. This property is only really useful if you are a
                              developer or are having problems with the driver.

charSet
                              The character set to use for data sent to the database or recieved
                     String
                              from the database.
                              Determine the number of PreparedStatement executions
prepareThreshold
                              required before switching over to use server side prepared
                     int
                              statements. The default is zero meaning never use server side
                              prepared statements.


24.5.5. Handling Errors
When making connections with external resources, errors are bound to occur, so you code
should make take such errors into account. Both JDBC and EnterpriseDB JDBC Connector
provide various types of errors. Our sample program demonstrates the use of this error
handling via the try/catch blocks which are there to capture a SQLException when it
occurs.

JDBC drivers implement three different pieces of error information. These are:

   1. The exception itself.
   2. The SQL State.
   3. A vendor code.

The following piece of code outputs the values of these three components should an error
occur when trying to accomplish some JDBC task.

System.out.println("SQL Exception: " + exp.getMessage());
System.out.println("SQL State: " + exp.getSQLState());
System.out.println("Vendor Error: " + exp.getErrorCode());

Suppose we try connecting to a database that does not exist on the specified host, then the
following error would be displayed on the console:

SQL Exception: Backend start-up failed: FATAL: database "dummy" does not
exist
Location: File: postinit.c, Routine: InitPostgres, Line: 272
Server SQLState: 3D000.

SQL State: 3D000

Vendor Error: 0

In a production system we would probably want to log the error to a log file so that we can
easily trace the cause of an error should it occur
4.6. Executing Queries through
Statement Objects
Following our example, by this time and point we have loaded our EnterpriseDB
JDBC Connector driver into our application and created a connection with a
EnterpriseDB database. The example code in our "HelloWorld" application then
builds a SQL Statement object, executes the SQL and then displays the results.

24.6.1. Building a Statement Object
The first step to getting data from an EnterpriseDB database is to build a Statement
object. The Statement object acts as a bridge between our database connection and
the results returned after executing an SQL statement. When a SQL Statement
object executes a query, it typically returns a ResultSet object. In our example,
this is achieved through the following piece of code:

Statement statement = con.createStatement();



24.6.2. Executing SQL
Once we have a Statement object in place, its time to execute SQL statements
designed to return results for use in our sample application. The Statement object
has several types of query methods each designed for a specific purpose. In this
section we will discuss the executeQuery() method which is designed to execute a
SQL statement that will return a result, meaning that this method expects to execute
a SELECT query.

In our example, the following line of code sets off this process:

ResultSet rs = statement.executeQuery("SELECT * FROM emp");


The executeQuery() method expects the SQL query to passed as a String, this
query is then passed to the database, which in turn executes this query.
EnterpriseDB JDBC Connector does not make any type of check on the validity
of the SQL statement being passed to the database. If for some reason the database
is unable to execute the SQL statement, a SQLException is thrown, otherwise, if all
goes well, the executeQuery() method will return a ResultSet object containing
the rows from the database.

In case the JVM is unable to locate the driver, it outputs a message to the console
and exits the application. The DriverManager is designed to handle multiple JDBC
driver objects as long as they register with a class, meaning that you can write a
Java application that connects with more than one database system via JDBC. Please
keep in mind that no connection is made with the database at this time and point,
and that the driver is simply loaded.

24.6.3. Displaying Results
Our example takes the ResultSet produced after the execution of our SQL query
and displays the first column (in this case the employee number, i.e. the empno
column) of each row in the emp table in our database.

24.6.4. Using the ResultSet Object
The ResultSet object is pretty much like a two-dimensional array, and acts as the
primary storage mechanism for the rows returned from a query on an EnterpriseDB
database.

The ResultSet object contains all of the rows returned by the database based on
the query that was executed. The columns of the ResultSet object are the fields
from the database as specified in the SQL query. If the SQL query used a * in the
SELECT (as we did in our example), then all the columns from the database will be
represented in the ResultSet. Whereas, if the columns are specified in the
SELECT statement, then only those columns will appear in the ResultSet.

A large number of getter methods are available for retrieving data from the
ResultSet object. These methods get the data from a specific database column and
attempt to convert that column's datatype to a Java datatype as specified by the
getter method.

You should keep the following points in mind when using the ResultSet interface:

   1. Before reading any values, you must call next(). This returns true if there is
      a result, but more importantly, it prepares the row for processing.
   2. Under the JDBC specification, you should access a field only once. It is
      safest to stick to this rule, although at the current time, the EnterpriseDB
      driver will allow you to access a field as many times as you want.
   3. You must close a ResultSet by calling close() once you have finished
      using it.
   4. Once you make another query with the Statement used to create a
      ResultSet, the currently open ResultSet instance is closed automatically.


24.6.5. More Advanced Example
Our first example included just the basics, now lets expand things a little by making
them more user friendly by adding a GUI to view our employee related information.
Later on we will take the GUI example further by adding variations to insert, update
and delete information in the database. This example makes use of two helper
classes:

      ConnectionUtils    - used for establishing the database connection, which
       keeps the database connection information in a properties file.
      Console   - used to provide a simple way to read from the console one line at
       a time

Let us first look at the properties file, and then the helper ConnectionUtils and
Console classes and then the SelectTest class making use of both of these classes.

resource.properties file

host=localhost
port=5444
db=edb
user=enterprisedb
password=enterprisedb

The helper "ConnectionUtils.java" Class

import java.sql.*;
import java.util.*;
/**
  * Utility class to mainipulate the database connections.
  */
public class ConnectionUtils
{
   private static Connection con = null;
   public static void main(String[] args)
   {
     ConnectionUtils.getConnection();
   }
   public static Connection getConnection()
   {
         try
     {
       Class.forName("com.edb.Driver");
       ResourceBundle rb = ResourceBundle.getBundle("resource");
       con =
DriverManager.getConnection("jdbc:edb://"+rb.getString("host")+
       ":"+rb.getString("port")+"/"+rb.getString("db")+
       "",""+rb.getString("user")+"",rb.getString("password"));
     }
         catch(ClassNotFoundException cnfe)
         {
       System.out.println("Unable to load the EDB JDBC Driver.");
       System.out.println("Please check your classpath property.");
       con = null;
     }
         catch(Exception exp)
         {
       System.out.println("Unable to Connect to the destination
database.");
       System.out.println("Please check that Host/ IP and the
authentication\r\n"+
                          "parameters are correct and the database
is listening the connections.");
       System.out.println("See below for full error description.");
       exp.printStackTrace();
       con = null;
     }
         return con;
    }
    public static void closeConnection()
    {
      try
          {
                  if(con!=null)
                          con.close();
      }
          catch(Exception exp)
          {
          }
    }
}

The helper "Console.java" Class

import java.io.*;
public class Console
{
  private static BufferedReader br = null;
  static
  {
    try
    {
       br = new BufferedReader(new InputStreamReader(System.in));
    }catch(Exception exp){}
  }
  public String readLine()
  {
    String line="";
    try
    {
      line = br.readLine();
    }catch(Exception exp)
    {}
    return line;
  }
}

SelectTest.java Class

import   java.sql.*;
import   java.util.Vector;
import   javax.swing.JFrame;
import   javax.swing.JScrollPane;
import   javax.swing.JTable;

public class SelectTest
{

  public static Vector getNextRow(ResultSet rs,int cols) throws
SQLException
  {
    Vector v = new Vector();
    for(int i=1;i<=cols;i++)
    {
      v.addElement(rs.getString(i));
    }
    return v;
  }
  public static void main(String[] args)
  {
    try
    {
      Connection con = ConnectionUtils.getConnection();
      Statement st = con.createStatement();
      ResultSet rs = st.executeQuery("SELECT * FROM EMP");
      ResultSetMetaData rsmd = rs.getMetaData();
      Vector labels = new Vector();
      Vector rows = new Vector();
      int cols = rsmd.getColumnCount();
      for(int i=0;i<cols;i++)
      {
        labels.addElement(rsmd.getColumnLabel(i+1));
      }
      while(rs.next())
      {
        rows.addElement(getNextRow(rs,cols));
      }
      JTable table = new JTable(rows,labels);
      JFrame jf = new JFrame("Browsing table: EMP ( from
EnterpriseDB)");
      jf.getContentPane().add(new JScrollPane(table));
      jf.setSize(400,400);
      jf.setVisible(true);
      jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      System.out.println("Command successfully executed");
    }catch(Exception exp){
      System.out.println("\r\nAn Error occured while executing the
query..");
      System.out.println("See full details below.\r\n");
      exp.printStackTrace();
    }
    ConnectionUtils.closeConnection();
  }
}

You should see the following when you compile and run the above sample
application.
Installation
To install Connect JDBC on your local drive:
1. Decide on an installation directory for Connect JDBC. Choose an existing
directory on your machine or create a new one.
2. Locate the Connect JDBC jar file in the appropriate platform-specific directory
on the DataDirect CD. Copy or download the jar file to the installation directory
on your machine.
3. Change to the Connect JDBC installation directory and unjar the contents of the
file. Enter:
jar -xvf jar_filename
where jar_filename is the name of the Connect JDBC jar file.
The Connect JDBC files are unjarred in the correct structure inside the
installation directory. Included in these files is the License Tool.
4. You must run the License Tool to complete the installation. Do one of the
following:
_ If you prefer to use a Graphical User Interface (GUI), go to "The GUI License

Tool" on page 2-2 for instructions.
_ If you prefer to use the command line, go to "The Command-Line License Tool"

on page 2-3 for instructions.
Installation
2-2 Oracle DataDirect Connect JDBC Installation Guide
The GUI License Tool
1. At a command prompt, change to the Connect JDBC installation directory.
2. Start the License Tool by entering the following command:
java -cp LicenseTool.jar com.merant.datadirect.jdbc.licensetool.LicenseTool
The JDBC License Tool dialog box appears.
You can exit at any time by clicking Close.
_ If this is a licensed installation, proceed to Step 3

_ If this is an evaluation installation, skip to Step 4

3. For a licensed installation, complete all of the fields as follows:
Key: Type the key for a licensed installation, which is provided to you by
DataDirect.
Driver: Type one of the following:
pack
db2
db2OS390
informix
sybase
sqlserver
Pack includes all the drivers; the other options are single-driver installations.
Installation Directory: Type the full path, including the drive letter on Windows
machines, of the Connect JDBC installation directory that you have chosen. Or,
you can browse to the directory by clicking the Browse (...) button.
Skip to Step 5
4. For an evaluation installation, complete all of the fields as follows:
Key: Type EVAL.
Driver: Type EVAL.
Installation Directory: Type the full path, including the drive letter on Windows
machines, of the Connect JDBC installation directory that you have chosen. Or,
you can browse to the directory by clicking the Browse (...) button.
Installation
Installation on Windows and UNIX 2-3
5. Click Finish to complete the installation.
6. When installation is complete, click Close to close the License Tool.
The Command-Line License Tool
1. At a command prompt, change to the Connect JDBC installation directory.
_If this is a licensed installation, proceed to Step 2
_If this is an evaluation installation, skip to Step 3
2. Run the License Tool for a licensed installation by specifying switches on the
command line. You must specify values for all of the switches. Use the
following syntax:
java -cp LicenseTool.jar com.merant.datadirect.jdbc.licensetool.LicenseTool
-k key -d driver_package -i installation_directory
where:
key is the key for a licensed installation, which is provided to you by DataDirect.
driver_package is one of the following:
pack
db2
db2OS390
informix
sybase
sqlserver
Pack includes all the drivers; the other options are single-driver installations.
installation_directory is the full path, including the drive letter on Windows
machines, to the Connect JDBC installation directory.
Note: An evaluation installation automatically installs all of the
drivers. If you later want to perform a licensed installation, simply
run the License Tool again.
Uninstalling

2-4 Oracle DataDirect Connect JDBC Installation Guide


Basic JDBC Programming Concepts:-
Important JDBC Concepts

Transactions: Whenever a connection is created by using the JDBC, then by default it is in
auto- commit mode. This means that SQL statement will be automatically committed
immediately after it is executed and it is treated as a transaction. But imagine a situation
where you want to execute a batch of statements, either they should commit at on go or they
should get failed together. For this we need to disable the auto- commit mode by using the
method:

con.setAutoCommit(false).

After setting the auto- commit as false, no SQL statement will be committed until we call the
con.commit() method. If there arises any problem while committing then the set of statements
will be rollback, without committing.

Logging: on the server--->logging--->JDBC.

By this we can enable JDBC logging and specify a log file name for the JDBC log.

Attributes of Logging:

1) Enable JDBC Logging: It determines whether the server has a JDBC log file.

2) JDBC Log File Name: It is the name of the log file.

Isolation: The isolation is needed when there are concurrent transactions. Concurrent
transactions are transactions are transactions that occurs at the same time. In isolation one
transaction does not interfere with another. For setting the isolation level for a JDBC
transaction, use the

Connection.setTransaction(int level) method

By using the snapshot isolation level we can only see the snapshot of the data locked by other
transactions when running from inside the transaction with snapshot isolation level.

Some of the transaction level are given below:

1). TRANSACTION_NONE

2). TRANSACTION_READ_UNCOMMITED

3. TRANSACTION_READ_COMMITTED

4. TRANSACTION_REPEATABLE_READ

5. TRANSACTION_SERIALIZABLE
By setting the isolation levels you are having an impact on the performance of the
transaction. You can get the existing isolation level with:

getTransactionIsolation() method.

Concurrency: Database concurrency controls ensure that the transactions occur in an ordered
fashion.

Concurrency control deals with the issue involved with allowing multiple people
simultaneous access to shared entities.

Query Execution:-


This is detailed java program to connect java application and execute queries like create table
in mysql database, insert some values and retrieve values from the table. Before running this
java code you need to copy a mysql connector jar file (mysql-connector-java-3.1.6-bin.jar) in
the jdk1.6.0_01\lib and set class path to this file.




ExecuteSqlQuery.java

 /**
* Execute sql queries with java application.
*/
import java.sql.*;
class ExecuteSqlQuery {
  public static void main(String[] args) {
  try {
  /* Create string of connection url within
            specified format with machine name,
  port number and database name. Here machine
            name id localhost and database
            name is usermaster. */
  String connectionURL =
            "jdbc:mysql://localhost:3306/usermaster";
  // declare a connection by using Connection interface
  Connection connection = null;
        // declare object of Statement interface that
            uses for executing sql statements.
  Statement statement = null;
            // declare a resultset that uses as a table for
              output data from the table.
    ResultSet rs = null;
    int updateQuery = 0;
    // Load JBBC driver "com.mysql.jdbc.Driver".
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    /* Create a connection by using getConnection()
              method that takes parameters of string type
              connection url, user name and password to
              connect to database. */
    connection = DriverManager.getConnection
              (connectionURL, "root", "root");

          /* createStatement() is used for create
              statement object that is used for sending sql
              statements to the specified database. */
    statement = connection.createStatement();
    // sql query of string type to create a data base.
    String QueryString = "CREATE TABLE
              user_master1(User_Id INTEGER NOT "+"NULL
              AUTO_INCREMENT, User_Name VARCHAR(25),
              UserId VARCHAR(20) "+ ", User_Pwd
              VARCHAR(15), primary key(User_Id))";
    updateQuery = statement.executeUpdate(QueryString);
    // sql query to insert values in the specified table.
    QueryString = "INSERT INTO user_master1
              (User_Name,UserId,User_Pwd) VALUES "+"('Mahendra
              ','mahendra25','1213456')";
    updateQuery = statement.executeUpdate(QueryString);
    if (updateQuery != 0) {
    System.out.println("table is created
                  successfully and " + updateQuery + " row is inserted.");
    }
    // sql query to retrieve values from the specified table.
    QueryString = "SELECT * from user_master1";
    rs = statement.executeQuery(QueryString);
    while (rs.next()) {
    System.out.println(rs.getInt(1) + " " + rs.getString(2) + "
                    " + rs.getString(3) + " "+rs.getString(4)+"\n");
    }
    // close all the connections.
    rs.close();
    statement.close();
    connection.close();
    }
    catch (Exception ex) {
    System.out.println("Unable to connect to batabase.");
    }
    }
}


Output of the program :
Download Source code




Scrollable and updatable resultset:-
In the last section, we have seen the ResultSet moving only in forward direction. In this
section, we learn some advance features of ResultSets. If some properties are set while
creating the ResultSet then we can randomly fetch the data and even update it witout any
update queries.

The next example demonstrates the advance features of the ResultSet.



package com.visualbuilder;



import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.Statement;



public class UpdateableAndScrollableRS {



     public static void main(String[] args) {



       try {
         /** Loading the driver*/

            Class.forName("com.mysql.jdbc.Driver");

         /** Getting Connection*/

                     Connection con =
DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","root");

         /** Creating Statement*/

                       Statement stmt =
con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDAT
ABLE);

         /** Getting ResultSet*/

                        ResultSet rs=stmt.executeQuery("select * from visualbuilder");

            while(rs.next()) {

                             System.out.print("Id is " + rs.getInt("id"));

                             System.out.println(" Name is "+rs.getString("name"));

                        }

                        rs.absolute(1);

                        rs.updateString(2,"Visual Builder");

                        rs.updateRow();

                        rs.beforeFirst();

                        System.out.println("After Updation");

                 while(rs.next()) {

                             System.out.print("Id is " + rs.getInt("id"));

                             System.out.println(" Name is "+rs.getString("name"));

                        }

         /** Closing the Connection*/

                        stmt.close();
                           con.close();

                    } catch (Exception e) {

                           e.printStackTrace();

                    }

           }

}



Output:-

Id is 1 Name is Sun java

Id is 2 Name is Visual Builder

Id is 3 Name is Eclipse

Id is 4 Name is IBM

Id is 5 Name is Jakarta

After Updation

Id is 1 Name is Visual Builder

Id is 2 Name is Visual Builder

Id is 3 Name is Eclipse

Id is 4 Name is IBM

Id is 5 Name is Jakarta


Metadata:-
Meta data is “data about data”. An item of metadata describes the specific characteristics
about an individual data item. In databases, metadata describes the structural components of
tables and their elements. For example, metadata about an element could include data types,
name of data, size and many more characteristics about that element. It would also give
information about the tables the database is storing, information, such as length of fields,
number of columns, where the tables are located and other pertinent information. One of the
main uses for met data is to provide a link between the information creator and the
information users. Meta data allows the users to speed up the search for individual data. This
is done by being able to set parameter for searches, allowing the filtering of unwanted
information. Meta data can be stored either internally, in the same file as the data or
externally, in a separate area. Both have advantages and disadvantages. I f the data is stored
internally, the meta data is together with the data making more easily accessible to view or
change. However, this method creates high redundancy. If metadata is stored externally, the
searches can become more efficient. There is no redundancy but getting to this metadata may
be a little more technical. There are certain formats that most be used, such as Uniform
Resource Identifier(URI) to get to the meta data, if this format is not used the meta data
becomes in accessible. All the metadata is stored in a data dictionary or a system catalog. All
programs that access data in the database work through a DBMS. The DBMS use the data
dictionary to look up the required components and relationships. Any changes made to the
database structure are automatically recorded in the data dictionary. This makes the data
dictionary manager’s job a lot easier, because any modification of programs that are affected
by changed structure is not necessary.



UPDATE

Metadata

Metadata at the most basic level is simply defined as “data about data”. An item of metadata
describes the specific characteristics about an individual data item. In the database realm,
metadata is defined as, “data about data, through which the end-user data are integrated and
managed.” (Rob & Coronel, 2009) Metadata in a database typically store the relationships
that link up numerous pieces of data. “Metadata names these fields, describes the size of the
fields, and may put restrictions on what can go in the field (for example, numbers
only).” (Sheldon, 2001).



“Therefore, metadata is information about how data is extracted, and how it may be
transformed. It is also about indexing and creating pointers into data. Database design is all
about defining metadata schemas.” (Sheldon, 2001) Meta data can be stored either internally,
in the same file as the data, or externally, in a separate area. If the data is stored internally,
the metadata is together with the data, making it more easily accessible to view or change.
However, this method creates high redundancy. If metadata is stored externally, the searches
can become more efficient. There is no redundancy but getting to this metadata may be a
little more technical.



All the metadata is stored in a data dictionary or a system catalog. The data dictionary is most
typically an external document that is created in a spreadsheet type of document that stores
the conceptual design ideas for the database schema. The data dictionary also contains the
general format that the data, and in effect the metadata, should be. Metadata is an essential
aspect to database design, it allows for increased processing power, due to the fact that it can
help create pointers and indexes.
This image is an example of a database schema that includes the metadata type that it is as
well as the information it is, including the size of information it can hold.




  Added by Buck9544

Rob, P., & Coronel, C. (2009). Database Systems Design, Implementation, And
Management. Boston: Course Technology.

Sheldon, T. (2001). Metadata. Retrieved 12 03, 2009, from Linktionary:
http://www.linktionary.com/m/metadata.html



UPDATE 10/14/2011



Definition

Metadata is defined as data that describes other data. Metadata can be divided into two main
types: structural and descriptive. Structural metadata describes the design structure and their
specifications. This type of metadata describes the containers of data within a database.
Descriptive metadata describes instances of application data. This is the type of metadata that
is traditionally spoken of and described as “data about the data.” A third type is sometime
identified called Adminitstrative metadata. Administrative metadata provides information
that helps to manage other information, such as when and how a resource was created, file
types and other technical information.

Metadata makes it easier to retrieve, use, or manage information resources by providing users
with information that adds context to the data they’re working with. Metadata can describe
information at any level of aggregation, including collections, single resources, or component
part of a single resource. Metadata can be embedded into a digital object or can be stored
separately.

Web pages contain metadata called metatags.

Examples:

e.g. A .mp3 audio file contains metadata that describes the length of the song, the artist, etc.

e.g. A word document contains metadata such as last time modified, length, author, etc.
Row Sets:-
Rowsets   make it easy to send tabular data over a network. They can also be used to provide
scrollable result sets or updatable result sets when the underlying JDBC driver does not
support them. These are the main uses for a rowset, and this tutorial will walk you through
examples of these uses. Because there can be so many variations in rowsets, the first part of
this chapter gives a conceptual description of rowsets and their uses. The next part walks you
through creating and using a rowset. The last part shows you how a rowset can be used in a
distributed Enterprise JavaBeans (EJB) application.



5.1 Types and Uses of Rowsets

A RowSet object contains a set of rows from a result set or some other source of tabular data,
like a file or spreadsheet. Because a RowSet object follows the JavaBeans model for
properties and event notification, it is a JavaBeans component that can be combined with
other components in an application. As is true with other Beans, application programmers
will probably use a development tool to create a RowSet object and set its properties.

Rowsets may have many different implementations to fill different needs. These
implementations fall into two broad categories, rowsets that are connected and those that are
disconnected. A disconnected rowset gets a connection to a data source in order to fill itself
with data or to propagate changes in data back to the data source, but most of the time it does
not have a connection open. While it is disconnected, it does not need a JDBC driver or the
full JDBC API, so its footprint is very small. Thus a rowset is an ideal format for sending
data over a network to a thin client.

Because it is not continually connected to its data source, a disconnected rowset stores its
data in memory. It needs to maintain metadata about the columns it contains and information
about its internal state. It also needs a facility for making connections, for executing
commands, and for reading and writing data to and from the data source. A connected rowset,
by contrast, opens a connection and keeps it open for as long as the rowset is in use.

Although anyone can implement a rowset, most implementations will probably be provided
by vendors offering RowSet classes designed for fairly specific purposes. To make writing an
implementation easier, the Java Software division of Sun Microsystems, Inc., plans to
provide reference implementations for three different styles of rowsets in the future. The
following list of planned implementations gives you an idea of some of the possibilities.

   1. A CachedRowSet class—a disconnected rowset that caches its data in memory; not suitable
      for very large data sets, but an ideal way to provide thin Java clients, such as a Personal
      Digital Assistant (PDA) or Network Computer (NC), with tabular data

   2. A JDBCRowSet class—a connected rowset that serves mainly as a thin wrapper around a
      ResultSet object to make a JDBC driver look like a JavaBeans component
   3. A WebRowSet class—a connected rowset that uses the HTTP protocol internally to talk to a
      Java servlet that provides data access; used to make it possible for thin web clients to
      retrieve and possibly update a set of rows




5.2 Using a Rowset

As the conceptual description of rowsets pointed out, what you can do with a rowset depends
on how it has been implemented. It can also depend on which properties have been set. The
example rowsets used in this chapter are based on the CachedRowSet implementation, but
because they are used for different purposes, one has several properties set whereas the other
has none. Among other things, this tutorial will show you which properties to use and when
to use them.

Getting back to our owner of The Coffee Break chain, he has had one of his developers write
an application that lets him project the effects of changing different coffee prices. To create
this application, the developer hooked together various JavaBeans components, setting their
properties to customize them for his application. The first JavaBeans component, called
Projector, was one that the owner bought from an economic forecasting firm. This Bean takes
all kinds of factors into account to project future revenues. Given the price and past sales
performance of a coffee, it predicts the revenue the coffee is likely to generate and displays
the results as a bar chart.

The second JavaBeans component is a CachedRowSet. The owner wants to be able to look at
different coffee pricing scenarios using his laptop, so the application is set up such that it
creates a rowset that can be copied to the laptop's disc. The owner can later fire up the
application on his laptop so that he can make updates to the rowset to test out various pricing
strategies.

The third Bean is a form for displaying and updating ResultSet objects. The form can be
used for displaying and updating our CachedRowSet because CachedRowSet is simply a
specialized implementation of ResultSet.

The application has a graphical user interface that includes buttons for opening and closing
the application. These buttons are themselves JavaBeans components that the programmer
assembled to make the GUI for his application.

While he is at work, the owner can click on the form's New Data button to get a rowset filled
with data. This is the work that requires the rowset to get a connection to the data source,
execute its query, get a result set, and populate itself with the result set data. When this work
is done, the rowset disconnects itself. The owner can now click on the Close button to save
the disconnected rowset to his laptop's disc. At home or on a plane, the owner can open the
application on his laptop and click the button Open to copy the rowset from disc and start
making updates using the form. The form displays the rowset, and he simply uses arrow keys
or tabs to highlight the piece of data he wants to update. He uses the editing component of the
form to type in new values, and the Projector Bean shows the effects of the new values in its
bar chart. When he gets back to headquarters, the owner can copy his updated rowset to his
office computer if he wants to propagate the updates back to the database.
As part of the implementation, the application programmer will do the following:

      Create the CachedRowSet Bean and set its properties

      Register the Projector Bean as a listener to the rowset

      Create the GUI for the application and implement the actions of the open and close buttons

      Specify the rowset as a property on the form Bean

To put this all together, the application programmer will probably use a visual Bean
development tool, which means that he will use very little RowSet API directly. Of course,
the owner will use the application without writing any RowSet code himself. The upshot of all
of this is that generally tools will generate the RowSet code you see in this tutorial. Also,
remember that the code shown here is for illustrative purposes only because it uses the
CachedRowSet class, for which there is no implementation currently available. Although the
JDBC Standard Extension specification gives a preliminary outline of its functionality, some
details in its implementation may be different when it is completed.

5.2.1 Creating a Rowset and Setting Properties

Because a programmer will generally use a Bean visual development tool to create a RowSet
object and set its properties, the example code fragments shown here would most likely be
executed by a Bean development tool. The main purpose of this section is to show you when
and why you would want to set certain properties.

The code for creating a CachedRowSet object simply uses the default constructor.

  CachedRowSet crset = new CachedRowSet();

Now the programmer can set the CachedRowSet object's properties to suit the owner's needs.
The RowSet interface, which the CachedRowSet class implements, contains get/set methods
for retrieving and setting properties. These properties and a RowSet object's event notification
capabilities (explained in a later section) are what make a RowSet object a JavaBeans
component. A rowset's properties include its command, concurrency, type, data source name,
url, user name, password, transaction isolation level, escape processing, maximum field size,
maximum rows, query timeout, and type map. You are required to set only those properties
that are needed for your particular use of a rowset. The following example uses several
properties and explains why they are needed.

The owner wants the convenience of being able to make updates by scrolling to the rows he
wants to update, so the property for the type needs to be set to scrollable. It may be that the
CachedRowSet class will be implemented so that it is by default TYPE_SCROLL_INSENSITIVE,
in which case the programmer would not need to set the rowset's type property. It does no
harm to set it, however. The default for the concurrency property is
ResultSet.CONCUR_READ_ONLY, so it needs to be set to CONCUR_UPDATABLE for our
entrepreneur's use. The following lines of code make the CachedRowSet object crset
scrollable and updatable.

  crset.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
  crset.setConcurrency(ResultSet.CONCUR_UPDATABLE);

The owner will want to make updates to the table COFFEES, so the programmer sets the
rowset's command string with the query SELECT * FROM COFFEES. When the method
execute is called, this command will be executed, and the rowset will be populated with the
data in the table COFFEES. The owner can then use the rowset to make his updates. In order to
execute its command, the rowset will need to make a connection with the database
COFFEEBREAK, so the programmer also needs to set the properties required for that. If the
DriverManager were being used to make a connection, he would set the properties for a
JDBC URL, a user name, and a password. However, he wants to use the preferred means of
getting a connection, which is to use a DataSource object, so he will set the properties for the
data source name, the owner's user name, and the owner's password. For security, the
programmer may opt to get the user name and password from the owner interactively at run
time, in which case he would not need to set them as properties. (If you need a refresher on
using a DataSource object to make a connection, start reading at page 160 in the advanced
tutorial.) Here is the code a tool would generate to set the command string, the data source
name, the user name, and the password properties for the CachedRowSet object crset.

  crset.setCommand("SELECT * FROM COFFEES");
  crset.setDataSourceName("jdbc/coffeesDB");
  crset.setUsername("juanvaldez");
  crset.setPassword("espresso");

Note that the String object set for the data source name is the logical name that the system
administrator (or someone acting in that capacity) registered with a JNDI naming service as
the logical name for the COFFEEBREAK database. A programmer just needs to get the logical
name, in this case jdbc/coffeesDB, from the system administrator and use it to set the data
source property. When the rowset makes a connection, it will use the information in its
properties, so the programmer or tool will not need to do anything except execute the
command string, which you will see later. Internally the rowset gives the JNDI naming
service the string the programmer set for the data source name property. Because
jdbc/coffeesDB was previously bound to a DataSource object representing the database
COFFEEBREAK, the naming service will return a DataSource object that the rowset can use to
get a connection to COFFEEBREAK.

The programmer sets one more property, the transaction isolation level, which determines the
transaction isolation level given to the connection that the rowset establishes. The owner does
not want to read any data that has not been committed, so the programmer chooses the level
TRANSACTION_READ_COMMITTED. The following line of code sets the rowset's property so that
"dirty reads" will not be allowed.

  crset.setTransactionIsolation(
          Connection.TRANSACTION_READ_COMMITTED);

The other properties are all optional for the owner, so the programmer does not set any
others. For example, he does not need to set a type map because there are no custom
mappings in the table COFFEES. If the owner has the programmer change the command string
so that it gets data from a table that has user-defined types with custom mappings, then the
type map property will need to be set.
5.2.2 Rowsets and Event Notification

Being a JavaBeans component, a RowSet object has the ability to participate in event
notification. In the application we are considering, the Projector Bean needs to be notified
when the rowset is updated, so it needs to be registered with the rowset as a listener. The
developer who wrote the Projector Bean will already have implemented the three
RowSetListener methods rowChanged, rowSetChanged, and cursorMoved. These methods
specify what the listener will do when an event occurs on the CachedRowSet object crset.
The Projector Bean does not care about where the cursor is, so its implementation of
cursorMoved is probably to do nothing. When one or more values in a row changes, the
method rowChanged will be called on the listener. This method will probably check to see if
the value in the PRICE or SALES columns has changed, and if either has changed, it will plug
the appropriate value(s) into its projection model to get a value to display. The method
rowSetChanged is invoked when the contents of the whole rowset change, which happens
only when the rowset's command string has been changed and then executed. This method
will probably have an implementation similar to that of the method rowChanged.

The following line of code registers projector, the bar chart component, as a listener for
crset.

  crset.addRowSetListener(projector);

Now that projector is registered as a listener with the rowset, it will be notified every time
an event occurs on crset.

The programmer will use his development tool to bring one more component into the
application, the editor that will be used to update the rowset. He does this by simply
specifying crset as a property on the editor. This tells the editor to which component it
should send the changes keyed into it.

5.2.3 Obtaining a Scrollable and Updatable Rowset

So far the programmer has created a CachedRowSet object and set its properties. Now all he
has to do in order to get a scrollable and updatable rowset is to call the method execute on
the rowset. As a result of this call, the rowset does all of the following behind the scenes:

      Gets a connection to the COFFEEBREAK database, using the properties for the data source
       name, the user name, and the password

      Executes the query SELECT * FROM COFFEES, which has been set as its command string
       property

      Fills the rowset with the data from the result set produced by the query

The invocation that accomplishes all of this is the following single line of code.

  crset.execute();

This produces a CachedRowSet object that contains the same data as the ResultSet object
generated by the query SELECT * FROM COFFEES. In other words, they both contain the data
in the table COFFEES. The difference is that because the application developer has set the
properties on the rowset to make it scrollable and updatable, the owner can move the cursor
to any position in the rowset and modify its data. This is true even if the ResultSet object
from which the rowset got its data is not scrollable or updatable. In fact, it is especially when
a JDBC driver does not support scrollable or updatable result sets that you might want to use
a rowset as a means of getting those capabilities.

5.2.4 Using a Rowset for Scrolling and Updating

Scrolling in a rowset is exactly the same as scrolling in a result set. The cursor is positioned
before the first row in a newly-populated rowset, and a call to the method next moves the
cursor to the first row. Thus, to iterate through a rowset from first row to last row, you call
the method next in a while loop, just as you would do for a ResultSet object. For example,
the following code fragment iterates through the entire RowSet object crset, printing the
name of every coffee in the table COFFEES.

  crset.execute();
  while (crset.next()) {
    System.out.println(crset.getString("COF_NAME"));
  }

With a non-scrollable rowset or result set, you are limited to iterating through the data once
and in a forward direction. With scrolling, you can move the cursor in any direction and can
go to a row as many times as you like. If you want a review of how to move the cursor, see
the advanced tutorial section "Moving the Cursor in Scrollable Result Sets" on page 109.

The owner of The Coffee Break wanted a scrolling rowset so that he could easily make
updates to a particular row. The following section illustrates moving the cursor to update a
row.

5.2.5 Updating a Rowset

Updating a CachedRowSet object is similar to updating a ResultSet object. The updateXXX
methods and the methods insertRow and deleteRow are inherited from ResultSet and are
used in the same way. For example, the owner has brought up the rowset, which contains the
current data in the table COFFEES, on his laptop computer. He wants to change the price for
French_Roast_Decaf, which is in the fifth row, so he moves the cursor there. The GUI tool
displaying the rowset will generate the following line of code to move the cursor to the fifth
row.

  crset.absolute(5);

The Projector Bean will be notified that the cursor has moved but will do nothing about it.

The owner now moves the cursor to the price, which is the third column, and changes the
column's value to 10.49. In response, the GUI tool generates the following update statement.

  crset.updateFloat(3, 10.49f);

Next the owner clicks on the ROW DONE button to indicate that he is finished making updates
to the current row. This causes the GUI tool to generate the following line of code.
  crset.updateRow();

The method rowChanged is called on the Projector Bean to notify it that a row in the rowset
has changed. The Projector Bean determines whether the price and/or number of pounds sold
has changed and, if so, plugs the most current price and number of pounds sold into its
projection calculations. After it arrives at new projected values for revenue from sales of the
affected coffee, it updates the bar chart to reflect the new values.

Now the owner moves to the previous row, which is the fourth row, changes the price to 9.49
and the sales amount to 500, and clicks the ROW DONE button. Note that the fourth column in
the rowset contains the number of pounds sold in the last week. The GUI tool generates the
following code.

  crset.previous(-1); // or crset.absolute(4);
  crset.updateFloat(3, 9.49f);
  crset.updateInt(4, 500);
  crset.updateRow();

So far the owner has updated the fourth and fifth rows in the rowset, but he has not updated
the values in the database. If this had been a ResultSet object, both the result set and the
database would have been updated with the call to the method updateRow. However, because
this is a disconnected rowset, the method CachedRowSet.acceptChanges has to be called for
the database to be updated. The owner will click the UPDATE DATABASE button if he wants to
propagate his changes back to the database. The GUI tool will generate the following line of
code.

  crset.acceptChanges();

The application is implemented so that the acceptChanges method is not actually invoked
until the owner returns to work and copies the updated rowset to his office computer. On the
office machine, the rowset can create a connection for writing updated values back to the
database. In addition to updating the database with the new values in rows four and five of
the rowset, the acceptChanges method will set the values that the rowset keeps as its
"original" values. Original values are the values the rowset had just before the current set of
updates.

Before writing new values to the database, the rowset's writer component works behind the
scenes to compare the rowset's original values with those in the database. If no one has
changed values in the table, the rowset's original values and the values in the database should
be the same. If there is no conflict, that is, the rowset's original values and the database's
values match, the writer may choose to write the updated values to the database, depending
on how it is implemented. The current values that the writer enters will be used as the original
values when a new set of updates is made. For example, the price in the fifth row was 9.99
before it was updated to 10.49. The rowset's original price of 9.99 should match the price for
French_Roast_Decaf coffee in the database. If it does, the writer can update the database
price to 10.49 and change the rowset's original price to 10.49. The next time the price for
French_Roast_Decaf is changed, the writer will compare the original value (10.49) with the
current value in the database.

In this example scenario you have seen how a rowset can be used to pass a set of rows to a
thin client, in this case a laptop computer. You have also seen how a rowset can provide
scrolling and updatability, which the JDBC driver used at the owner's office does not support.
The next part of this chapter will show you how a rowset might be used in an EJB
application.



5.3 An EJB Example

For this example, we assume that you are familiar with the concepts discussed in "Basic
Tutorial" and "Advanced Tutorial," especially the sections on using the JDBC Standard
Extension API. This EJB example gives only a high-level explanation of the EJB classes and
interfaces used in it; if you want a more thorough explanation, you should see the EJB
specification available at the following URL:

  http://java.sun.com/products/ejb

Let's assume that the owner of The Coffee Break has set up an EJB application to make it
easier for his managers to order coffee for their stores. The managers can bring up an order
form that has two buttons: one button for viewing a table with the coffees and prices currently
available and another button for placing an order.

The developer who designed the form used JavaBeans components to create the buttons,
layout, and other components of the form. The application developer will use Enterprise
JavaBeans components to make the buttons do their work. The EJB component (enterprise
Bean) will be deployed in a container provided by an EJB server. The container manages the
life cycle of its enterprise Beans and also manages the boundaries of the transactions in which
they participate. The EJB implementation also includes a DataSource class that works with
an XADataSource class to provide distributed transactions.

5.3.1 A Distributed Application

An EJB application is always a distributed application, an application that distributes its work
among different machines. An EJB application uses the three-tier model. The first tier is the
client, which is typically a web browser. In our example, the client is a form running on The
Coffee Break's intranet. The second tier, or middle tier, is made up of the EJB server and the
JDBC driver. The third tier is one or more database servers.

The method getCoffees is one of the three methods that is implemented by our enterprise
Bean, the class CoffeesBean. Let's look at the implementation of this method, which creates
and populates a rowset, and then look at how its invocation and execution are spread out over
the three tiers. This method will be explained in more detail later in this chapter.

  public RowSet getCoffees() throws SQLException {
  Connection con = null;
  try {
    con = ds.getConnection("managerID", "mgrPassword");
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(
              "SELECT COF_NAME, PRICE FROM COFFEES");
    CachedRowSet rset = new CachedRowSet();
       crset.populate(rs);
       rs.close();
         stmt.close();
         return crset;
       }

       finally {
         if (con != null) con.close();
       }
       return null;
  }




      1. Client—invokes the method getCoffees
         The manager clicks the button Display Coffee Prices on The Coffee Break order form.

      2. Middle tier—starts executing the method getCoffees
         The EJB server creates a connection to the DBMS server and sends the query to it.

      3. DBMS server(s)—executes the query sent from the middle tier
         The DBMS server executes the query and returns a result set with coffee names and their
         prices to the middle tier server.

      4. Middle tier—finishes executing the method getCoffees
         The middle tier server creates a rowset, populates it with the data from the result set
         returned by the DBMS, and returns the rowset to the client.

      5. Client—the order form displays the rowset received from the middle tier

Note that a distributed application is not restricted to three tiers: It may have two tiers, a
client and server. Also note that a distributed application is different from a distributed
transaction. A distributed transaction, often referred to as a global transaction, is a transaction
that involves two or more DBMS servers. A global transaction will always occur within the
context of a distributed application because by definition it requires at least a client and two
servers.

5.3.2 Differences in Rowsets

As you have just seen, the rowset used in our EJB example is a CachedRowSet object that is
created and populated on the middle tier server. This disconnected rowset is then sent to a
thin client. All of this is also true of the rowset in the laptop example, but there are some
differences between the two rowsets. The main difference is that the rowset used in the order
form for The Coffee Break is not updatable by the client; it is simply a list of coffees and
their prices that the manager can look at. Therefore, the rowset does not need its concurrency
property set. In fact, the rowset used in the order form does not need any properties at all set.
The method getCoffees gets a DataSource object and then uses it to get a connection, so
the rowset does not need to perform these tasks. This means that the rowset does not use a
data source name, user name, or password and thus does not need the properties for them set.
The order form rowset also needs no command property because the getCoffees
implementation executes the query to get coffee names and prices. Recall that by contrast, the
rowset in the laptop example created a connection, executed its command string, and
populated itself with data by having its execute method invoked. The only CachedRowSet
method used in the EJB example is populate, which just reads data from the ResultSet
object passed to it and inserts the data into the rowset.




Transactions:-
A transaction is a sequence of operations performed as a single logical unit of work. A logical
unit of work must exhibit four properties, called the atomicity, consistency, isolation, and
durability (ACID) properties, to qualify as a transaction.

Atomicity

       A transaction must be an atomic unit of work; either all of its data modifications are
       performed, or none of them is performed.

Consistency

       When completed, a transaction must leave all data in a consistent state. In a relational
       database, all rules must be applied to the transaction's modifications to maintain all
       data integrity. All internal data structures, such as B-tree indexes or doubly-linked
       lists, must be correct at the end of the transaction.

Isolation

       Modifications made by concurrent transactions must be isolated from the
       modifications made by any other concurrent transactions. A transaction either
       recognizes data in the state it was in before another concurrent transaction modified it,
       or it recognizes the data after the second transaction has completed, but it does not
       recognize an intermediate state. This is referred to as serializability because it results
       in the ability to reload the starting data and replay a series of transactions to end up
       with the data in the same state it was in after the original transactions were performed.

Durability

       After a transaction has completed, its effects are permanently in place in the system.
       The modifications persist even in the event of a system failure.

Specifying and Enforcing Transactions


SQL programmers are responsible for starting and ending transactions at points that enforce
the logical consistency of the data. The programmer must define the sequence of data
modifications that leave the data in a consistent state relative to the organization's business
rules. The programmer includes these modification statements in a single transaction so that
the SQL Server Database Engine can enforce the physical integrity of the transaction.

It is the responsibility of an enterprise database system, such as an instance of the Database
Engine, to provide mechanisms ensuring the physical integrity of each transaction. The
Database Engine provides:

      Locking facilities that preserve transaction isolation.
      Logging facilities that ensure transaction durability. Even if the server hardware,
       operating system, or the instance of the Database Engine itself fails, the instance uses
       the transaction logs upon restart to automatically roll back any uncompleted
       transactions to the point of the system failure.
      Transaction management features that enforce transaction atomicity and consistency.
       After a transaction has started, it must be successfully completed, or the instance of
       the Database Engine undoes all of the data modifications made since the transaction
       started

       Introduction of LDAP:-
LDAP is a standard that computers and networked devices can use to access common
information over a network. The ability to provide network access to data in itself does not
make LDAP stand out from dozens of other protocols defined for data access, such as
Hypertext Transfer Protocol (HTTP). As you will see in this chapter and those following, a
number of features and vendor efforts make LDAP very well-suited for access and updates to
many types of common information.

For example, information about employees might be stored in a directory so that people and
applications can locate their contact information. Such contact information might include
email addresses and fax numbers, or even additional data that unambiguously identifies
employees' attempts to access enterprise applications.

1.1.2 LDAP and directory services

LDAP provides client-server access to directories over a computer network and is therefore a
directory service. In addition to offering the ability to search and read information, it defines
a way to add, update, and delete information in a directory.

Two general types of directory server software implement the LDAP standards:

      Stand-alone LDAP servers
      LDAP gateway servers

Stand-alone LDAP servers focus exclusively on LDAP as their only access mechanism; their
proprietary internal data stores are tuned for LDAP access. These are typically what people
mean when they use the words LDAP server.

Instead of being tied to a local data store, LDAP gateway servers translate between LDAP
and some other native network protocol or application program interface (API) to provide
access to directory information that is more directly available via other means. One example
is the original use of LDAP: to gateway to other directory services supporting the X.500
standards. Another more modern example of such an LDAP gateway is a server that provides
LDAP access to information residing in Oracle database tables.

Figure 1.1 illustrates the two types of services that can be used to provide LDAP-enabled
directory services.




Figure 1.1
LDAP directories and LDAP gateways are different types of products that provide
LDAP-enabled directory services.

The examples throughout this book will not address one type of server over the other—the
idea behind LDAP is that it shouldn't matter where the end data is stored, as long as the client
and server can use LDAP to communicate that information in a standard way understood by
both sides.

In addition, we will focus primarily on accessing and managing information and services
through the LDAP protocol. Each directory server product is installed and configured
differently, usually in ways that are well-documented in product manuals. It would be of little
use to duplicate such information, because installation and configuration of the software is
relatively trivial

.

Basic LDAP concepts
LDAP is used to store relatively static information. The phrase "write once read many times"
describes the best use of LDAP. LDAP is structured as a directory optimized for lookups. Its
tree structure is useful for conceptualizing organizational structures.

Each entry in the LDAP tree is composed of one or more object classes. Every object class
has attributes stored in name value pairs. An example of an LDAP attribute name value pair
is uid=c0001.

The LDAP schema specifies:

   a. The object classes and names used for the entries in the LDAP tree.
   b. The names of the attributes and the types of operations supported by each attribute.

The structure of your LDAP tree will be based on a schema.


Figure 1. General structure of an LDAP tree
An entry can be located in LDAP by specifying either the distinguished name (dn) or the
relative distinguished name (rdn). The dn is the full LDAP tree path whereas the rdn is just a
unique identifier for a specific entry in the tree.

One way to easily conceptualize the difference between the dn and rdn is to think of the
difference between directions and an address. The dn would be equivalent to giving
directions from the airport to a hotel. The rdn would just be the address of the hotel. Similar
to an address a rdn must be unique. It would be very difficult to find your hotel on a city map
if its address was not unique.

Back to top

Employee Data Stored in LDAP

For your project, the LDAP setup will be relatively simple—a linear list of employee entries.

Build the distinguished names for the employees using the uid attribute in the distinguished
name (dn). For example, the dn for the manager Barbara Jensen is
uid=c0001,ou=people,dc=ibm,dc=com. The value for the uid is a unique company id. By
using a company id instead of the name you can more easily maintain your LDAP. For
example, if Barbara gets married and changes her name to Barbara Jensen-Howard, you only
need to change two attributes: cn=Barbara Jensen-Howard and sn=Jensen-Howard. If you
used cn=Barbara Jensen,ou=people,dc=ibm,dc=com for the distinguished name then you
would have to delete the entire LDAP entry and regenerate it as cn=Barbara Jensen-
Howard,ou=people,dc=ibm,dc=com. Also consider the case where you have two employees
with the same name. The use of a company id prevents name collisions in your LDAP tree.

Below is a table of employee names in the Billing Department and their corresponding name
found in LDAP. The second column lists the employee's dn. The third column shows the
employee's rdn


Table 1. Employees distinguished and relative distinguished names in LDAP
Employee       Distinguished Name (dn) in LDAP Relative Distinguished Name (rdn)
Name                                               in LDAP
Barbara Jensen uid=c0001,ou=people,dc=ibm,dc=comuid=c0001
Stu Pretzman uid=c0002,ou=people,dc=ibm,dc=comuid=c0002
Varad Singh uid=c0003,ou=people,dc=ibm,dc=comuid=c0003
Steven Moyer uid=c0004,ou=people,dc=ibm,dc=comuid=c0004
Carla VanDykeuid=c0005,ou=people,dc=ibm,dc=comuid=c0005
Billy Parker uid=c0006,ou=people,dc=ibm,dc=comuid=c0006

Barbara Jensen is the manager of the Billing Department. The other five entries are her
employees. Each entry in LDAP contains useful employee information such as a telephone
number, mailing address and email.

You will use these employee records from the Billing Department to populate the LDAP tree.
During the course of the article you will add, modify and delete LDAP entries for these
employee records.
Back to top

Setup of IBM Tivoli Directory Server

In order to learn about LDAP, it is useful to have an LDAP server installed on your
computer. The following steps demonstrate how to install the IBM Tivoli Directory Server on
Windows.

Download IBM Tivoli Directory Server for Windows from IBM.

Unzip the install zip file to a temp directory. In the ismp folder, double-click the setup.exe
icon to launch the wizard. Choose English as the install wizard language. Accept the license
agreement.


Figure 2. Welcome Screen




Choose English as the language. On the subsequent panels, you will be prompted for
installation of the directory server components.
Figure 3. Language




If you already have DB2, the GSKit or the WebSphere Application Server - Express edition
installed, then the wizard will detect it. However, DB2 must be installed on the same server
as your LDAP server. Otherwise you will have to install these components. Install the Web
Administration Tool and the IBM WebSphere Application Server – Express although you
will not need them to complete the exercise in this article. Click Next.
Figure 4. Features




The LDAP server install will commence. When you get to this panel, click the Next button
until you get to the restart your computer panel.


Figure 5. Additional screens
On the penultimate panel, the setup will ask you to restart your computer. Select the Yes
radio button. Click Next.


Figure 6. Restart computer




Click the Finish button. Your computer will restart.
Figure 7. Required restart of computer




After your computer restarts, you should login again using the same user id. The IBM Tivoli
Directory Server Configuration Tool will automatically launch.
Figure 8. Directory Server Configuration Tool




Click on the Administrator DN/password task. Set the administrator id to cn=root Enter
ibm4root for the password. Click on the OK button.



Figure 9. Change administrator DN and password
The administrator id cn=root is the master LDAP user id and should only be used for tasks
such as modifications to the LDAP tree. It should never be given to LDAP users.

Then choose the Configure database task. Choose Create a new database. Click on the Next
button. Enter a user id and password for the database. Click Next. Name the database
pcldap. Make sure the default (UTF-8/UCS-2) code set is selected. Click Next. Select a
drive letter. Click the Next button and then Finish. After the database installation is
complete, press the Close button.


Figure 10. Configure database




Select Manage suffixes in the task bar. Enter dc=ibm, dc=com. This is suffix of the schema.
Press the Add button. You will designate dc=ibm,dc=com as the base suffix for your LDAP
group. Click OK to save the changes. In the future you could insert additional base suffixes.


Figure 11. Manage suffixes
At this point you will populate your LDAP with the employee entries. Select Import LDIF
data. A LDIF (Lightweight Directory Interchange Format) file is an ASCII file format used
to load and save the data contained in a LDAP tree. In addition to containing the actual data
entries, an LDIF file will also contain the objects used to form the schema.

Browse to the setup.ldif file. Select the Remove trailing spaces in Standard Import or
Bulkload check box. This is a Standard import. Click the Import button. After the import
completes, press Clear results. Then press the Close button. The LDAP server cannot be
running when you are importing LDIF data using the Directory Configuration Tool.


Figure 12. Import LDIF (Lightweight Directory Interchange Format) data




Close the Directory Server Configuration Tool by selecting in the menu bar File => Close.

Back to top

Starting the LDAP Server

Before you start the LDAP server you must have a defined IP address for your server. If your
server has a static IP address you can ignore this step. If you are not using a static IP address
then you have two options. For either option, you must know the name of your server. Enter
hostname from the command line. To use the first option, launch a command prompt and
enter ipconfig.


Figure 13. Command prompt - ipconfig output
Enter this IP address in your <window os directory>\system32\drivers\etc\hosts file.
Restart your server. This will allow your LDAP server to run and other servers to connect
your LDAP as long as that dynamic IP address remains bound to your computer. Remember
to remove this entry from the hosts file after you are done with your testing. If you are just
using your LDAP server for local development, then you can implement the second option.
Just add an alias for your server name to local host address 127.0.0.1. In the <window os
directory>\system32\drivers\etc\hosts file, add the following entry. This local host
alias can remain in your hosts file.

# for LDAP testing
127.0.0.1<your server name goes here>

If you do not heed this warning you will forever be plagued with bind errors and the LDAP
server will never start.

You can start the LDAP server from the command line using the
<ldapinstalldir>\bin\ibmslapd.exe command or use the Services panel. The LDAP
server is the IBM Tivoli Directory Server V5.2 entry shown below. For some configuration
changes using the IBM Tivoli Directory Server Configuration Tool you must stop the
Directory Server. The Admin Daemon should never be stopped.


Figure 14. Admin Daemon is for LDAP administration; Directory Server is the LDAP
server.




Back to top

Viewing the LDAP Tree

The Tivoli Directory Server has a web client that can be run from the WebSphere Express
Server. The war file can also be installed on a WebSphere server.

Back to top

Adding an entry from the command line

IBM hires a new employee named Susan Baker. Although you could use the LDAP browser,
an employee entry has too many attributes. You can add the employee using the ldapadd
command and the addemployee.ldif file. In the <ldapserver directory>\bin directory,
enter on the command line:

ldapadd -h ldap://<ldaphostname> -D "cn=root" -w ibm4root -f
<ldif_directory_path>addemployee.ldif



The LDIF file used to add the employee Susan Baker is shown below.
Listing 1. addemployee.ldif file
# this is a comment the # must be in FIRST column

version: 1

## ------------------------------------------------------------------------
------------
## ePerson is an AUXILLIARY objectclass from IBM and must
## have a STRUCTURAL objectclass (inetOrgPerson in this case)
##
## this is an entry sequence and is preceded by a blank line

dn: uid=c0007,ou=people,dc=ibm,dc=com
objectclass: ePerson
objectclass: inetOrgPerson
cn: Susan Baker
sn: Baker
givenName: Susan
initials: SAB
title: Billing worker
uid: c0007
userpassword: hellome1
mail: sbaker@ibm.com
mail: susan.baker@ibm.com
homephone: +1 999 111 3425
telephoneNumber: +1 999 555 1262
facsimileTelephoneNumber: +1 999 555 1292
mobile: +1 999 555 141
roomNumber: 0220
carLicense: 6ABDE3
o: ibm
ou: Billing
departmentNumber: 2604
registeredAddress: 348 Parkside Dr Anywhere, IL 23480
postalAddress: 347 Parkside Dr. Anywhere, IL 23480
employeeNumber: 9899
employeeType: full time
preferredLanguage: en
labeledURI: http://www-1.ibm.com/servers/eserver/iseries/ldap/schema/




There are several benefits to using the command line for loading LDIF files versus the Tivoli
Directory Server Configuration Tool. The command line is much faster than the graphical
user interface. You also do not have to stop the LDAP server to load the LDIF file. Stopping
a production LDAP server may cause some excitement amongst the users. After running
ldapadd you must refresh the directory tree in the LDAP browser if you want to see the
updates. Select the dc=ibm,dc=com entry and press the Refresh icon.

Back to top

Viewing an Entry from the Command line

View your update using ldapsearch. From a command line enter:

ldapsearch -h ldap://<ldaphostname> -D "cn=root" -w ibm4root -b
"ou=people,dc=ibm,dc=com" "uid=c0007"



The –b indicates where you want to start your search of the tree. Since you added the entry
for Susan Baker at ou=people,dc=ibm,dc=com you begin the search at that level in the tree.
You can also search the entire tree dc=ibm,dc=com for Susan’s record using:

ldapsearch -h ldap://<ldaphostname> -D "cn=root" -w ibm4root -b
"dc=ibm,dc=com" "uid=c0007"



Back to top

Deleting an Entry from the Command line

Employee Billy Parker spent several days trying to install the IBM Tivoli Directory Server on
a server that did not have a static IP address and he did not update his hosts file. His manager,
Barbara, discovered his incompetence and Billy is fired. You remove him from the company
LDAP using the ldapdelete command.

ldapdelete -h ldap://<ldaphostname> -D "cn=root" -w ibm4root
"uid=c0006,ou=people,dc=ibm,dc=com"



Back to top

Modifying an Entry from the Command line

Billing Department manager Barbara Jensen moves to a new house and her new home phone
number also changes to +1 999 222 3423. She also adds another telephone line at work, +1
999 243 2312, and places her picture on the company’s web site. You update her employee
record using the following line.

ldapadd -h ldap://<ldaphostname> -D "cn=root" -w ibm4root -f
<ldif_directory_path>modifyemployee.ldif



The LDIF file for modifying Barbara Jensen’s entry is shown below. The – in the file allows
multiple attribute updates.


Listing 2. modifyemployee.ldif file
# this is a comment the # must be in first column
version: 1


## -----------------------------------------------------------
## ePerson is an AUXILLIARY objectclass from IBM and must
## have a STRUCTURAL objectclass (inetOrgPerson in this case)
## - Modify the Barbara Jensen entry setup in setup.ldif.
#
# Change her telephones and add a jpg.
#
## this is an entry sequence and is preceded by a blank line

dn: uid=c0001,ou=people,dc=ibm,dc=com
changetype: modify
add: telephonenumber +1 999 243 2312
telephonenumber: +1 999 243 2312
-
replace: homephone
homephone: +1 999 222 3423
-
add: jpegphoto
jpegphoto: http://www.ibm.com/photo/babs.jpg




Back to top

Format of the Command line Operations

The general format of the LDAP commands discussed is shown in the table below.


Table 2. LDAP command line operations
Operation Format
Add or      ldapadd -h ldap://<ldaphostname> -D <root DN> -w <root password> -f
Modify      <ldif_file_path>
Search      ldapsearch -h ldap://<ldaphostname> -D <root DN> -w <root password> -b
            <base search DN> <search DN>
Delete      ldapdelete -h ldap://<ldaphostname> -D <root DN> -w <root password> <DN
            to be deleted>

Back to top

Displaying the LDAP data from Internet Explorer

An interesting feature associated with Internet Explorer is an Address Book that ties into your
LDAP server. Launch Internet Explorer and type the following URL in your address bar.

ldap://<ldaphostname>/ou=people,dc=ibm,dc=com??one?(objectclass=*)



The Address Book program in Internet Explorer will launch allowing you to view the
employees in your address book.
Figure 15. Internet Explorer Address




Back to top

Overview of the LDIF File Format

The Lightweight Data Interchange Format (LDIF) is used to represent LDAP entries in a
simple text format. This section provides a brief description of the LDIF entry format.

The basic form of an entry is shown below. An entry sequence is preceded by a blank line. A
comment is denoted by a # in the first column. Also a space must follow the : in an attribute.

# comment line
dn: <distinguished name>
<attrdesc>: <attrvalue>
<attrdesc>: <attrvalue>
<attrdesc>: <attrvalue>
...



Review the addemployee.ldif file for Susan Baker.
Listing 3. addemployee.ldif file
# this is a comment the # must be in FIRST column

version: 1

##   -----------------------------------------------------------------
##   ePerson is an AUXILLIARY objectclass from IBM and must
##   have a STRUCTURAL objectclass (inetOrgPerson in this case)
##
##   this is an entry sequence and is preceded by a blank line

dn: uid=c0007,ou=people,dc=ibm,dc=com
objectclass: ePerson
objectclass: inetOrgPerson
cn: Susan Baker
sn: Baker
givenName: Susan
initials: SAB
title: Billing worker
uid: c0007
userpassword: hellome1
mail: sbaker@ibm.com
mail: susan.baker@ibm.com
homephone: +1 999 111 3425
telephoneNumber: +1 999 555 1262
facsimileTelephoneNumber: +1 999 555 1292
mobile: +1 999 555 141
roomNumber: 0220
carLicense: 6ABDE3
o: ibm
ou: Billing
departmentNumber: 2604
registeredAddress: 348 Parkside Dr Anywhere, IL 23480
postalAddress: 347 Parkside Dr. Anywhere, IL 23480
employeeNumber: 9899
employeeType: full time
preferredLanguage: en
labeledURI: http://www-1.ibm.com/servers/eserver/iseries/ldap/schema/




The lines starting with a # character are comments. You can have multiple # characters but
they must be followed by a space. The version number is so you can keep track of changes to
this file. The first line of the entry sequence is the distinguished name (dn). The uid attribute
is the key used to locate this entry in the tree. Hence the relative distinguished name (rdn) for
this entry would be uid=c0007. The entry for Susan Baker is located under the people
organization unit (ou). The people organizational unit is located under the base
dc=ibm,dc=com entry.

The next two lines define the object class for the entry containing Susan Baker’s information.
The base LDAP schemas provide you with the inetOrgPerson object for storing information
about a person. However, it lacks many attributes needed in today’s business environment.
For example, inetOrgPerson does not have a mobile telephone attribute. The IBM Tivoli
Directory Server provides an auxiliary class, ePerson, which has many useful attributes such
as mobile and postalAddress. A full list of all the schemas provided by IBM can be
downloaded from the Tivoli schema repository.
The remainder of the LDIF file contains various personal attributes for Susan Baker.

Back to top

Accessing LDAP Data Using Java

Java provides an excellent framework for accessing the data stored in LDAP. The procedure
is similar to other types of access to a remote resource. You open a connection to the LDAP
server. You perform the operation such as read, write or delete. You close the connection.

Opening the LDAP Connection

The Java Naming and Directory Interface (JNDI) is used to access an LDAP server. A
DirContext object is the conduit for your Java program to attach to LDAP. Using the
DirContext is simple. You construct a Properties object with the URL of the LDAP
server, the root user name and password and several Java housekeeping items (context
factory, security principal and referral). This Properties object is passed into the constructor
for the DirContext.

All of the snippets mentioned below refer to source code in the TestLDAP.java program.

//--------------------------------------------------
// Set up the environment for creating the initial context
//--------------------------------------------------
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");

props.setProperty(Context.PROVIDER_URL, "ldap://<lpadserver>:389");
props.setProperty(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");

props.setProperty(Context.REFERRAL, "ignore");
props.setProperty(Context.SECURITY_AUTHENTICATION, "simple");

// --------------------------------------------------
//specify the root username
// --------------------------------------------------
props.setProperty(Context.SECURITY_PRINCIPAL, "cn=root");

//--------------------------------------------------
//specify the root password
// --------------------------------------------------
props.setProperty(Context.SECURITY_CREDENTIALS, "ibm4root");

//--------------------------------------------------
// Get the environment properties (props) for creating initial
// context and specifying LDAP service provider parameters.
//--------------------------------------------------
DirContext ctx = new InitialDirContext(props);



Searching LDAP

Once you have established a connection to the LDAP server, you can search the tree for
either a matching entry or attributes.
First you need to setup some constraints for your search. In the TestLDAP.java program, the
constraints are all set to SUBTREE_SCOPE.

SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);



Below is a table of all the scope parameter variables supported by setSearchScope().


Table 3. setSearchScope() parameters
Values for             What it does
setSearchScope()
SUBTREE_SCOPE               Starts at the base entry and searches the base entry and everything
                            below it. This is the slowest and most extensive search.
ONELEVEL_SCOPE              Searches on the entries below the base entry.
OBJECT_SCOPE                Searches only the base entry. This is the fastest and least extensive
                            search.

The next step is to configure the entity attributes that will be filled in as a result of the search.
Since all the interesting entities belong to the ePerson schema, the returning attributes field
is set to an array of all the possible ePerson attributes.

constraints.setReturningAttributes(EPERSON_ATTRIBUTE_LIST);



Next is the search. The BASE_SEARCH define is just set to ou=people,dc=ibm,dc=com, which
is the parent of the tree of employees. Different formats of search filters are also specified in
the source.

NamingEnumeration results = ctx.search(BASE_SEARCH, filter, constraints);



The search filter can have any of the following formats.


Table 4. Search filters
SymbolFilter            Example                      Example matches
  ~= Approximate            sn~=Jensen               Any variations in Jensen
   =   Equality              sn=Jensen               Only matches surname Jensen. This is the
                                                     most common search format.
   >    Greater Than              sn>Jensen          Any surname that alphabetically follows
                                                     Jensen. e.g. Pretzman.
   >=   Greater Than or          sn>=Jensen          Surname matching Jensen or following it
        Equal                                        alphabetically.
    <   Less Than                 sn<Jensen          Surname that precedes Jensen. e.g. Baker
   <=   Less Than or             sn<=Jensen          Surname matching or preceding Jensen.
        Equal
   =*   Presence of                  sn=*            Any entry that contains a sn attribute.
        Attribute
   *    Wildcard String           sn=Jen*n           Any matching string, substring, or
         Match                                   superstring that matches Jensen.
     &   And                (&(sn=Jensen)        Any entry that matches all the conditions.
                           (initials=BJJ))       In this case, surname of Jensen with the
                                                 initials of BJJ.
     |   Or                 (|(sn=Jensen)        Any entry that matches either condition.
                           (initials=BJJ))       The surname of Jensen or the initials of BJJ
     !   Not                  (sn=Jensen)        The negative of the enclosed condition. All
                                                 surnames except Jensen.

After the search, the program iterates through the result set using the NamingEnumeration
returned by the context. Each attribute is printed out.

if (results.hasMoreElements())
{
        System.out.println(" has returned results..\n");
        bFoundIt = true;
        // Since UID is unique across the entire directory,
        // the search results should contain only one entry.
        SearchResult sr = (SearchResult) results.next();
        // ---------------------------------------------
        // Get all available attribute types and their associated
        // values and print them out.
        // ---------------------------------------------
        printAttributes(sr.getAttributes());
}
else
{
        System.out.println(" has returned no results..");
}



Updating Attributes

The code for updating the attributes of an entry is similar to the search. First the program
must find the entry to be updated in the same search manner as described above. At that point
the attributes for an entry may be changed, added or removed. The ModificationItem object
is used to alter the attribute represented by the BasicAttribute object.

// Get all available attribute types and their associated
// values.
Attributes attributes = sr.getAttributes();

// Specify the changes to make
ModificationItem[] mods = new ModificationItem[1];

//   -------------------------------------------
//   remove the attribute
//   -------------------------------------------
if   (bRemoveAttribute) {
          // eliminate the attribute
          if (null != attributes.get(attrName)) {
                   mods[0] = new ModificationItem(
                                 DirContext.REMOVE_ATTRIBUTE,
                                 new BasicAttribute(attrName, attrVal));
          }
}
// -------------------------------------------
// replace or add the attribute
// -------------------------------------------
else {
        // do a replace of the attribute
        if (null != attributes.get(attrName)) {
                mods[0] = new ModificationItem(
                        DirContext.REPLACE_ATTRIBUTE,
                                new BasicAttribute(attrName, attrVal));
        }
        // add the attribute
            else {
                mods[0] = new ModificationItem(
                        DirContext.ADD_ATTRIBUTE, new BasicAttribute(
                                               attrName, attrVal));
        }
}

ctx.modifyAttributes(updateDN + "," + BASE_SEARCH, mods);



Close the connection

After performing any operation to the LDAP server you must close the connection. By
placing the close call in a finally block you are guaranteed that the LDAP connection will
always be closed.

//always close the directory context when you are done
finally {
        try {
                if (null != ctx)
                        ctx.close();
        } catch (Exception e2) {
        }
}




Run the sample program

To run the LDAP sample program, enter java -jar createLDAP.jar on a command line.



Conclusion

If you have made it to this point you should have a working knowledge of LDAP. You
understand the concept of distinguished and relative distinguished names. You know the
steps to install the IBM Tivoli Directory Server. You can add, modify or delete LDAP entries
using the LDAP Browser and from the command line. You understand the format of an LDIF
file. Finally you have learned how to use JNDI to programmatically access your LDAP
server.
Basic LDAP concepts

LDAP is used to store relatively static information. The phrase "write once read many times"
describes the best use of LDAP. LDAP is structured as a directory optimized for lookups. Its
tree structure is useful for conceptualizing organizational structures.

Each entry in the LDAP tree is composed of one or more object classes. Every object class
has attributes stored in name value pairs. An example of an LDAP attribute name value pair
is uid=c0001.

The LDAP schema specifies:

   a. The object classes and names used for the entries in the LDAP tree.
   b. The names of the attributes and the types of operations supported by each attribute.

The structure of your LDAP tree will be based on a schema.
Figure 1. General structure of an LDAP tree




An entry can be located in LDAP by specifying either the distinguished name (dn) or the
relative distinguished name (rdn). The dn is the full LDAP tree path whereas the rdn is just a
unique identifier for a specific entry in the tree.

One way to easily conceptualize the difference between the dn and rdn is to think of the
difference between directions and an address. The dn would be equivalent to giving
directions from the airport to a hotel. The rdn would just be the address of the hotel. Similar
to an address a rdn must be unique. It would be very difficult to find your hotel on a city map
if its address was not unique.

Back to top

Employee Data Stored in LDAP

For your project, the LDAP setup will be relatively simple—a linear list of employee entries.
Build the distinguished names for the employees using the uid attribute in the distinguished
name (dn). For example, the dn for the manager Barbara Jensen is
uid=c0001,ou=people,dc=ibm,dc=com. The value for the uid is a unique company id. By
using a company id instead of the name you can more easily maintain your LDAP. For
example, if Barbara gets married and changes her name to Barbara Jensen-Howard, you only
need to change two attributes: cn=Barbara Jensen-Howard and sn=Jensen-Howard. If you
used cn=Barbara Jensen,ou=people,dc=ibm,dc=com for the distinguished name then you
would have to delete the entire LDAP entry and regenerate it as cn=Barbara Jensen-
Howard,ou=people,dc=ibm,dc=com. Also consider the case where you have two employees
with the same name. The use of a company id prevents name collisions in your LDAP tree.

Below is a table of employee names in the Billing Department and their corresponding name
found in LDAP. The second column lists the employee's dn. The third column shows the
employee's rdn


Table 1. Employees distinguished and relative distinguished names in LDAP
Employee       Distinguished Name (dn) in LDAP Relative Distinguished Name (rdn)
Name                                               in LDAP
Barbara Jensen uid=c0001,ou=people,dc=ibm,dc=comuid=c0001
Stu Pretzman uid=c0002,ou=people,dc=ibm,dc=comuid=c0002
Varad Singh uid=c0003,ou=people,dc=ibm,dc=comuid=c0003
Steven Moyer uid=c0004,ou=people,dc=ibm,dc=comuid=c0004
Carla VanDykeuid=c0005,ou=people,dc=ibm,dc=comuid=c0005
Billy Parker uid=c0006,ou=people,dc=ibm,dc=comuid=c0006

Barbara Jensen is the manager of the Billing Department. The other five entries are her
employees. Each entry in LDAP contains useful employee information such as a telephone
number, mailing address and email.

You will use these employee records from the Billing Department to populate the LDAP tree.
During the course of the article you will add, modify and delete LDAP entries for these
employee records.

Back to top

Setup of IBM Tivoli Directory Server

In order to learn about LDAP, it is useful to have an LDAP server installed on your
computer. The following steps demonstrate how to install the IBM Tivoli Directory Server on
Windows.

Download IBM Tivoli Directory Server for Windows from IBM.

Unzip the install zip file to a temp directory. In the ismp folder, double-click the setup.exe
icon to launch the wizard. Choose English as the install wizard language. Accept the license
agreement.
Figure 2. Welcome Screen




Choose English as the language. On the subsequent panels, you will be prompted for
installation of the directory server components.


Figure 3. Language
If you already have DB2, the GSKit or the WebSphere Application Server - Express edition
installed, then the wizard will detect it. However, DB2 must be installed on the same server
as your LDAP server. Otherwise you will have to install these components. Install the Web
Administration Tool and the IBM WebSphere Application Server – Express although you
will not need them to complete the exercise in this article. Click Next.


Figure 4. Features




The LDAP server install will commence. When you get to this panel, click the Next button
until you get to the restart your computer panel.
Figure 5. Additional screens




On the penultimate panel, the setup will ask you to restart your computer. Select the Yes
radio button. Click Next.


Figure 6. Restart computer
Click the Finish button. Your computer will restart.


Figure 7. Required restart of computer




After your computer restarts, you should login again using the same user id. The IBM Tivoli
Directory Server Configuration Tool will automatically launch.
Figure 8. Directory Server Configuration Tool




Click on the Administrator DN/password task. Set the administrator id to cn=root Enter
ibm4root for the password. Click on the OK button.



Figure 9. Change administrator DN and password
The administrator id cn=root is the master LDAP user id and should only be used for tasks
such as modifications to the LDAP tree. It should never be given to LDAP users.

Then choose the Configure database task. Choose Create a new database. Click on the Next
button. Enter a user id and password for the database. Click Next. Name the database
pcldap. Make sure the default (UTF-8/UCS-2) code set is selected. Click Next. Select a
drive letter. Click the Next button and then Finish. After the database installation is
complete, press the Close button.


Figure 10. Configure database




Select Manage suffixes in the task bar. Enter dc=ibm, dc=com. This is suffix of the schema.
Press the Add button. You will designate dc=ibm,dc=com as the base suffix for your LDAP
group. Click OK to save the changes. In the future you could insert additional base suffixes.


Figure 11. Manage suffixes
At this point you will populate your LDAP with the employee entries. Select Import LDIF
data. A LDIF (Lightweight Directory Interchange Format) file is an ASCII file format used
to load and save the data contained in a LDAP tree. In addition to containing the actual data
entries, an LDIF file will also contain the objects used to form the schema.

Browse to the setup.ldif file. Select the Remove trailing spaces in Standard Import or
Bulkload check box. This is a Standard import. Click the Import button. After the import
completes, press Clear results. Then press the Close button. The LDAP server cannot be
running when you are importing LDIF data using the Directory Configuration Tool.


Figure 12. Import LDIF (Lightweight Directory Interchange Format) data




Close the Directory Server Configuration Tool by selecting in the menu bar File => Close.

Back to top

Starting the LDAP Server

Before you start the LDAP server you must have a defined IP address for your server. If your
server has a static IP address you can ignore this step. If you are not using a static IP address
then you have two options. For either option, you must know the name of your server. Enter
hostname from the command line. To use the first option, launch a command prompt and
enter ipconfig.


Figure 13. Command prompt - ipconfig output
Enter this IP address in your <window os directory>\system32\drivers\etc\hosts file.
Restart your server. This will allow your LDAP server to run and other servers to connect
your LDAP as long as that dynamic IP address remains bound to your computer. Remember
to remove this entry from the hosts file after you are done with your testing. If you are just
using your LDAP server for local development, then you can implement the second option.
Just add an alias for your server name to local host address 127.0.0.1. In the <window os
directory>\system32\drivers\etc\hosts file, add the following entry. This local host
alias can remain in your hosts file.

# for LDAP testing
127.0.0.1<your server name goes here>

If you do not heed this warning you will forever be plagued with bind errors and the LDAP
server will never start.

You can start the LDAP server from the command line using the
<ldapinstalldir>\bin\ibmslapd.exe command or use the Services panel. The LDAP
server is the IBM Tivoli Directory Server V5.2 entry shown below. For some configuration
changes using the IBM Tivoli Directory Server Configuration Tool you must stop the
Directory Server. The Admin Daemon should never be stopped.


Figure 14. Admin Daemon is for LDAP administration; Directory Server is the LDAP
server.




Back to top

Viewing the LDAP Tree

The Tivoli Directory Server has a web client that can be run from the WebSphere Express
Server. The war file can also be installed on a WebSphere server.

Back to top

Adding an entry from the command line

IBM hires a new employee named Susan Baker. Although you could use the LDAP browser,
an employee entry has too many attributes. You can add the employee using the ldapadd
command and the addemployee.ldif file. In the <ldapserver directory>\bin directory,
enter on the command line:

ldapadd -h ldap://<ldaphostname> -D "cn=root" -w ibm4root -f
<ldif_directory_path>addemployee.ldif



The LDIF file used to add the employee Susan Baker is shown below.
Listing 1. addemployee.ldif file
# this is a comment the # must be in FIRST column

version: 1

## ------------------------------------------------------------------------
------------
## ePerson is an AUXILLIARY objectclass from IBM and must
## have a STRUCTURAL objectclass (inetOrgPerson in this case)
##
## this is an entry sequence and is preceded by a blank line

dn: uid=c0007,ou=people,dc=ibm,dc=com
objectclass: ePerson
objectclass: inetOrgPerson
cn: Susan Baker
sn: Baker
givenName: Susan
initials: SAB
title: Billing worker
uid: c0007
userpassword: hellome1
mail: sbaker@ibm.com
mail: susan.baker@ibm.com
homephone: +1 999 111 3425
telephoneNumber: +1 999 555 1262
facsimileTelephoneNumber: +1 999 555 1292
mobile: +1 999 555 141
roomNumber: 0220
carLicense: 6ABDE3
o: ibm
ou: Billing
departmentNumber: 2604
registeredAddress: 348 Parkside Dr Anywhere, IL 23480
postalAddress: 347 Parkside Dr. Anywhere, IL 23480
employeeNumber: 9899
employeeType: full time
preferredLanguage: en
labeledURI: http://www-1.ibm.com/servers/eserver/iseries/ldap/schema/




There are several benefits to using the command line for loading LDIF files versus the Tivoli
Directory Server Configuration Tool. The command line is much faster than the graphical
user interface. You also do not have to stop the LDAP server to load the LDIF file. Stopping
a production LDAP server may cause some excitement amongst the users. After running
ldapadd you must refresh the directory tree in the LDAP browser if you want to see the
updates. Select the dc=ibm,dc=com entry and press the Refresh icon.

Back to top

Viewing an Entry from the Command line

View your update using ldapsearch. From a command line enter:

ldapsearch -h ldap://<ldaphostname> -D "cn=root" -w ibm4root -b
"ou=people,dc=ibm,dc=com" "uid=c0007"



The –b indicates where you want to start your search of the tree. Since you added the entry
for Susan Baker at ou=people,dc=ibm,dc=com you begin the search at that level in the tree.
You can also search the entire tree dc=ibm,dc=com for Susan’s record using:

ldapsearch -h ldap://<ldaphostname> -D "cn=root" -w ibm4root -b
"dc=ibm,dc=com" "uid=c0007"



Back to top

Deleting an Entry from the Command line

Employee Billy Parker spent several days trying to install the IBM Tivoli Directory Server on
a server that did not have a static IP address and he did not update his hosts file. His manager,
Barbara, discovered his incompetence and Billy is fired. You remove him from the company
LDAP using the ldapdelete command.

ldapdelete -h ldap://<ldaphostname> -D "cn=root" -w ibm4root
"uid=c0006,ou=people,dc=ibm,dc=com"



Back to top

Modifying an Entry from the Command line

Billing Department manager Barbara Jensen moves to a new house and her new home phone
number also changes to +1 999 222 3423. She also adds another telephone line at work, +1
999 243 2312, and places her picture on the company’s web site. You update her employee
record using the following line.

ldapadd -h ldap://<ldaphostname> -D "cn=root" -w ibm4root -f
<ldif_directory_path>modifyemployee.ldif



The LDIF file for modifying Barbara Jensen’s entry is shown below. The – in the file allows
multiple attribute updates.


Listing 2. modifyemployee.ldif file
# this is a comment the # must be in first column
version: 1


## -----------------------------------------------------------
## ePerson is an AUXILLIARY objectclass from IBM and must
## have a STRUCTURAL objectclass (inetOrgPerson in this case)
## - Modify the Barbara Jensen entry setup in setup.ldif.
#
# Change her telephones and add a jpg.
#
## this is an entry sequence and is preceded by a blank line

dn: uid=c0001,ou=people,dc=ibm,dc=com
changetype: modify
add: telephonenumber +1 999 243 2312
telephonenumber: +1 999 243 2312
-
replace: homephone
homephone: +1 999 222 3423
-
add: jpegphoto
jpegphoto: http://www.ibm.com/photo/babs.jpg




Back to top

Format of the Command line Operations

The general format of the LDAP commands discussed is shown in the table below.


Table 2. LDAP command line operations
Operation Format
Add or      ldapadd -h ldap://<ldaphostname> -D <root DN> -w <root password> -f
Modify      <ldif_file_path>
Search      ldapsearch -h ldap://<ldaphostname> -D <root DN> -w <root password> -b
            <base search DN> <search DN>
Delete      ldapdelete -h ldap://<ldaphostname> -D <root DN> -w <root password> <DN
            to be deleted>

Back to top

Displaying the LDAP data from Internet Explorer

An interesting feature associated with Internet Explorer is an Address Book that ties into your
LDAP server. Launch Internet Explorer and type the following URL in your address bar.

ldap://<ldaphostname>/ou=people,dc=ibm,dc=com??one?(objectclass=*)



The Address Book program in Internet Explorer will launch allowing you to view the
employees in your address book.
Figure 15. Internet Explorer Address




Back to top

Overview of the LDIF File Format

The Lightweight Data Interchange Format (LDIF) is used to represent LDAP entries in a
simple text format. This section provides a brief description of the LDIF entry format.

The basic form of an entry is shown below. An entry sequence is preceded by a blank line. A
comment is denoted by a # in the first column. Also a space must follow the : in an attribute.

# comment line
dn: <distinguished name>
<attrdesc>: <attrvalue>
<attrdesc>: <attrvalue>
<attrdesc>: <attrvalue>
...



Review the addemployee.ldif file for Susan Baker.
Listing 3. addemployee.ldif file
# this is a comment the # must be in FIRST column

version: 1

##   -----------------------------------------------------------------
##   ePerson is an AUXILLIARY objectclass from IBM and must
##   have a STRUCTURAL objectclass (inetOrgPerson in this case)
##
##   this is an entry sequence and is preceded by a blank line

dn: uid=c0007,ou=people,dc=ibm,dc=com
objectclass: ePerson
objectclass: inetOrgPerson
cn: Susan Baker
sn: Baker
givenName: Susan
initials: SAB
title: Billing worker
uid: c0007
userpassword: hellome1
mail: sbaker@ibm.com
mail: susan.baker@ibm.com
homephone: +1 999 111 3425
telephoneNumber: +1 999 555 1262
facsimileTelephoneNumber: +1 999 555 1292
mobile: +1 999 555 141
roomNumber: 0220
carLicense: 6ABDE3
o: ibm
ou: Billing
departmentNumber: 2604
registeredAddress: 348 Parkside Dr Anywhere, IL 23480
postalAddress: 347 Parkside Dr. Anywhere, IL 23480
employeeNumber: 9899
employeeType: full time
preferredLanguage: en
labeledURI: http://www-1.ibm.com/servers/eserver/iseries/ldap/schema/




The lines starting with a # character are comments. You can have multiple # characters but
they must be followed by a space. The version number is so you can keep track of changes to
this file. The first line of the entry sequence is the distinguished name (dn). The uid attribute
is the key used to locate this entry in the tree. Hence the relative distinguished name (rdn) for
this entry would be uid=c0007. The entry for Susan Baker is located under the people
organization unit (ou). The people organizational unit is located under the base
dc=ibm,dc=com entry.

The next two lines define the object class for the entry containing Susan Baker’s information.
The base LDAP schemas provide you with the inetOrgPerson object for storing information
about a person. However, it lacks many attributes needed in today’s business environment.
For example, inetOrgPerson does not have a mobile telephone attribute. The IBM Tivoli
Directory Server provides an auxiliary class, ePerson, which has many useful attributes such
as mobile and postalAddress. A full list of all the schemas provided by IBM can be
downloaded from the Tivoli schema repository.
The remainder of the LDIF file contains various personal attributes for Susan Baker.

Back to top

Accessing LDAP Data Using Java

Java provides an excellent framework for accessing the data stored in LDAP. The procedure
is similar to other types of access to a remote resource. You open a connection to the LDAP
server. You perform the operation such as read, write or delete. You close the connection.

Opening the LDAP Connection

The Java Naming and Directory Interface (JNDI) is used to access an LDAP server. A
DirContext object is the conduit for your Java program to attach to LDAP. Using the
DirContext is simple. You construct a Properties object with the URL of the LDAP
server, the root user name and password and several Java housekeeping items (context
factory, security principal and referral). This Properties object is passed into the constructor
for the DirContext.

All of the snippets mentioned below refer to source code in the TestLDAP.java program.

//--------------------------------------------------
// Set up the environment for creating the initial context
//--------------------------------------------------
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");

props.setProperty(Context.PROVIDER_URL, "ldap://<lpadserver>:389");
props.setProperty(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");

props.setProperty(Context.REFERRAL, "ignore");
props.setProperty(Context.SECURITY_AUTHENTICATION, "simple");

// --------------------------------------------------
//specify the root username
// --------------------------------------------------
props.setProperty(Context.SECURITY_PRINCIPAL, "cn=root");

//--------------------------------------------------
//specify the root password
// --------------------------------------------------
props.setProperty(Context.SECURITY_CREDENTIALS, "ibm4root");

//--------------------------------------------------
// Get the environment properties (props) for creating initial
// context and specifying LDAP service provider parameters.
//--------------------------------------------------
DirContext ctx = new InitialDirContext(props);



Searching LDAP

Once you have established a connection to the LDAP server, you can search the tree for
either a matching entry or attributes.
First you need to setup some constraints for your search. In the TestLDAP.java program, the
constraints are all set to SUBTREE_SCOPE.

SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);



Below is a table of all the scope parameter variables supported by setSearchScope().


Table 3. setSearchScope() parameters
Values for             What it does
setSearchScope()
SUBTREE_SCOPE               Starts at the base entry and searches the base entry and everything
                            below it. This is the slowest and most extensive search.
ONELEVEL_SCOPE              Searches on the entries below the base entry.
OBJECT_SCOPE                Searches only the base entry. This is the fastest and least extensive
                            search.

The next step is to configure the entity attributes that will be filled in as a result of the search.
Since all the interesting entities belong to the ePerson schema, the returning attributes field
is set to an array of all the possible ePerson attributes.

constraints.setReturningAttributes(EPERSON_ATTRIBUTE_LIST);



Next is the search. The BASE_SEARCH define is just set to ou=people,dc=ibm,dc=com, which
is the parent of the tree of employees. Different formats of search filters are also specified in
the source.

NamingEnumeration results = ctx.search(BASE_SEARCH, filter, constraints);



The search filter can have any of the following formats.


Table 4. Search filters
SymbolFilter            Example                      Example matches
  ~= Approximate            sn~=Jensen               Any variations in Jensen
   =   Equality              sn=Jensen               Only matches surname Jensen. This is the
                                                     most common search format.
   >    Greater Than              sn>Jensen          Any surname that alphabetically follows
                                                     Jensen. e.g. Pretzman.
   >=   Greater Than or          sn>=Jensen          Surname matching Jensen or following it
        Equal                                        alphabetically.
    <   Less Than                 sn<Jensen          Surname that precedes Jensen. e.g. Baker
   <=   Less Than or             sn<=Jensen          Surname matching or preceding Jensen.
        Equal
   =*   Presence of                  sn=*            Any entry that contains a sn attribute.
        Attribute
   *    Wildcard String           sn=Jen*n           Any matching string, substring, or
         Match                                   superstring that matches Jensen.
     &   And                (&(sn=Jensen)        Any entry that matches all the conditions.
                           (initials=BJJ))       In this case, surname of Jensen with the
                                                 initials of BJJ.
     |   Or                 (|(sn=Jensen)        Any entry that matches either condition.
                           (initials=BJJ))       The surname of Jensen or the initials of BJJ
     !   Not                  (sn=Jensen)        The negative of the enclosed condition. All
                                                 surnames except Jensen.

After the search, the program iterates through the result set using the NamingEnumeration
returned by the context. Each attribute is printed out.

if (results.hasMoreElements())
{
        System.out.println(" has returned results..\n");
        bFoundIt = true;
        // Since UID is unique across the entire directory,
        // the search results should contain only one entry.
        SearchResult sr = (SearchResult) results.next();
        // ---------------------------------------------
        // Get all available attribute types and their associated
        // values and print them out.
        // ---------------------------------------------
        printAttributes(sr.getAttributes());
}
else
{
        System.out.println(" has returned no results..");
}



Updating Attributes

The code for updating the attributes of an entry is similar to the search. First the program
must find the entry to be updated in the same search manner as described above. At that point
the attributes for an entry may be changed, added or removed. The ModificationItem object
is used to alter the attribute represented by the BasicAttribute object.

// Get all available attribute types and their associated
// values.
Attributes attributes = sr.getAttributes();

// Specify the changes to make
ModificationItem[] mods = new ModificationItem[1];

//   -------------------------------------------
//   remove the attribute
//   -------------------------------------------
if   (bRemoveAttribute) {
          // eliminate the attribute
          if (null != attributes.get(attrName)) {
                   mods[0] = new ModificationItem(
                                 DirContext.REMOVE_ATTRIBUTE,
                                 new BasicAttribute(attrName, attrVal));
          }
}
// -------------------------------------------
// replace or add the attribute
// -------------------------------------------
else {
        // do a replace of the attribute
        if (null != attributes.get(attrName)) {
                mods[0] = new ModificationItem(
                        DirContext.REPLACE_ATTRIBUTE,
                                new BasicAttribute(attrName, attrVal));
        }
        // add the attribute
            else {
                mods[0] = new ModificationItem(
                        DirContext.ADD_ATTRIBUTE, new BasicAttribute(
                                               attrName, attrVal));
        }
}

ctx.modifyAttributes(updateDN + "," + BASE_SEARCH, mods);



Close the connection

After performing any operation to the LDAP server you must close the connection. By
placing the close call in a finally block you are guaranteed that the LDAP connection will
always be closed.

//always close the directory context when you are done
finally {
        try {
                if (null != ctx)
                        ctx.close();
        } catch (Exception e2) {
        }
}



Back to top

Run the sample program

To run the LDAP sample program, enter java -jar createLDAP.jar on a command line.

Back to top

Conclusion

If you have made it to this point you should have a working knowledge of LDAP. You
understand the concept of distinguished and relative distinguished names. You know the
steps to install the IBM Tivoli Directory Server. You can add, modify or delete LDAP entries
using the LDAP Browser and from the command line. You understand the format of an LDIF
file. Finally you have learned how to use JNDI to programmatically access your LDAP
server.
                              DISTRIBUTED OBJECTS

The Roles of Client and Server:-
Periodically, the programming community starts thinking of “objects everywhere” as the
solution to all its problems. The idea is to have a happy family of collaborating objects that
can be located anywhere. These objects are, of course, supposed to communicate through
standard protocols across a network. For example, you'll have an object on the client where
the user can fill in a request for data. The client object sends a message to an object on the
server that contains the details of the request. The server object gathers the requested
information, perhaps by accessing a database or by communicating with additional objects.
Once the server object has the answer to the client request, it sends the answer back to the
client. Like most bandwagons in programming, this plan contains a fair amount of hype that
can obscure the utility of the concept. This chapter

The Roles of Client and Server

Let's go back to that idea of locally collecting information on a client computer and sending
the information across a network to a server. We are supposing that a user on a local machine
will fill out an information request form. The data is sent to the vendor's server. The server
processes the request and will, in turn, want to send back product information the client can
view, as shown in Figure 5-1.
                  Figure 5-1. Transmitting objects between client and server




Remote Method Invocations:-
Java Remote Method Invocation (Java RMI) enables the programmer to create distributed
Java technology-based to Java technology-based applications, in which the methods of
remote Java objects can be invoked from other Java virtual machines, possibly on different
hosts. RMI uses object serialization to marshal and unmarshal parameters and does not
truncate types, supporting true object-oriented polymorphism.

API Specification
      java.rmi Package
      java.rmi.dgc Package
      java.rmi.registry Package
      java.rmi.server Package
      java.rmi.activation Package
Architecture and Functional Specification
     Java RMI Specification

Tutorials
     Getting Started
      The Getting Started Tutorial shows you the steps to follow to create a distributed
      version of the classic Hello World program using Java RMI. The Hello World applet
      makes a remote method call to the server from which it was downloaded to retrieve
      the message "Hello World!"

     Using Custom Socket Factories with Java RMI
      The "Using Custom Socket Factories with Java RMI" tutorial shows you how to
      create a version of the distributed Hello World program in which the Java RMI
      runtime uses sockets of a type chosen by the programmer. This tutorial also includes a
      discussion of how Java RMI can be used over SSL sockets.

     The Activation Tutorials
     The Activation Tutorials describe how to use the Java RMI APIs to implement, to
      register, and to use activatable objects. Each tutorial presents a different way to
      implement an activatable object. All tutorials use the same parameterized setup
      program that registers information about an activatable object with the Java RMI
      Activation System Daemon (rmid).

     Configuring inetd to Launch rmid
     The Internet services daemon inetd, supported on the Solaris Operating System
      (Solaris OS), provides an alternative to starting up services at system boot time. This
      daemon, a server process for Internet standard services, can be configured to start
      services on demand.

     Designing Services to be Launched from inetd
     This tutorial describes how to structure a service program (employing a specially
      exported local registry) so that the service can be started from inetd when clients
      connect to the service's local registry, and how to configure inetd to launch the
      service program.
     Dynamic code downloading using Java RMI (Using the
      java.rmi.server.codebase Property)
      One of the most significant capabilities of the Java platform is the ability to
      dynamically download Java software from any URL to a VM running in a separate
      process, usually on a different physical system. The result is that a remote system can
      run a program, for example an applet, which has never been installed on its disk. This
      tutorial describes the use of dynamic code downloading in a Java system, and how it
      can be used with Java RMI.
     The Java RMI trail of The Java Tutorial Continued
      This trail provides a brief overview of the Java RMI system and then walks through a
      complete client/server example that uses Java RMI's unique capabilities to load and to
      execute user-defined tasks at runtime. The server in the example implements a generic
      compute engine, which the client uses to compute the value of pi.
Enhancements
        Java RMI Release Notes
         The release notes describe enhancements and changes to the Java RMI APIs and
         implementation, as well to the associated tools, rmic, rmiregistry, and rmid.



The following classes implement a simple client-server program using RMI that displays a
message.

RmiServer    class—Listens to RMI requests and implements the interface which is used by the
client to invoke remote methods.

import    java.rmi.Naming;
import    java.rmi.RemoteException;
import    java.rmi.RMISecurityManager;
import    java.rmi.server.UnicastRemoteObject;
import    java.rmi.registry.*;

public class RmiServer extends UnicastRemoteObject
    implements RmiServerIntf {
    public static final String MESSAGE = "Hello world";

       public RmiServer() throws RemoteException {
       }

       public String getMessage() {
           return MESSAGE;
       }


       public static void main(String args[]) {
           System.out.println("RMI server started");

           // Create and install a security manager
           if (System.getSecurityManager() == null) {
               System.setSecurityManager(new RMISecurityManager());
               System.out.println("Security manager installed.");
           } else {
               System.out.println("Security manager already exists.");
           }

           try { //special exception handler for registry creation
               LocateRegistry.createRegistry(1099);
               System.out.println("java RMI registry created.");
           } catch (RemoteException e) {
               //do nothing, error means registry already exists
               System.out.println("java RMI registry already exists.");
           }

           try {
               //Instantiate RmiServer
               RmiServer obj = new RmiServer();

                // Bind this object instance to the name "RmiServer"
                Naming.rebind("//localhost/RmiServer", obj);
               System.out.println("PeerServer bound in registry");
           } catch (Exception e) {
               System.err.println("RMI server exception:" + e);
               e.printStackTrace();
           }
     }
}




The Java allows us to develop distributed applications using RMI. Distributed computing refers to the
application design paradigm in which programs, the data they process, and the actual computations
are spread
over a network either to leverage the processing power of multiple computers or due to the
inherent nature of an
application computing different modules.

RMI (Remote method Invocation) allows object-o-object communication between different Java
Virtual
Machines (JVMs).

JVMs can be distinct entities located on the same or separate computers –yet one JVM can invoke
methods
belonging to an object stored on another JVM. This enables applications to call object methods
located
remotely, sharing resources, and processing load across systems. Methods can even pass objects
that a foreign
virtual machine has never encountered before, allowing the dynamic loading of new classes as
required. This is
really a quite powerful feature.

Other Alternatives to RMI:
• Sockets
• EJB
• CORBA
• DCOM

Basic network programming with sockets is flexible and sufficient for communication between
programs.
However, it requires all the involved parties to communicate via application-level protocols, the
design of
which is complex and can be error prone. For example, consider a collaborative application like a
simple chat
application for instance: for multiple clients to participate we would first need to design some sort of
protocol,
and then use sockets to communicate in that protocol with the server. RMI, on the other hand, is a
distributed
system that internally uses sockets over TCP/IP.

       Send to friend
       Permalink
       Add a comment


RMI Architecture
RMI’s purpose is to make objects in separate JVM’s look alike and act like local objects. The JVM that
calls the
remote object is usually referred to as a client and the JVM that contains the remote object is the
server.

One of the most important aspects of the RMI design is its intended transparency. Applications do
not know
whether an object is remote or local. A method invocation on the remote object has the same syntax
as a method
invocation on a local object, though under the hood there is a lot more going on.

• In RMI the term “Server” does not refers to a physical server or application but to a single remote
objecthaving methods that can be remotely invoked.Similarly the Term “Client” does not refer to a
client m/c but actually refers to the object invoking a remote method on a remote object.
• The same object can be both a client and a server.
   Although obtaining a reference to a remote object is somewhat different from doing so for local
objects. Once

we have the reference, we use the remote object as if it were local. The RMI infrastructure will
automatically
intercept the method call, find the remote object and process the request remotely. This location
transparency
even includes garbage collection.

A remote object is always accessed via its remote interface. In other words the client invokes
methods on the
object only after casting the reference to the remote interface.

The RMI implementation is essentially built from three abstraction layers:
• The Stub/Skeleton Layer
• The Remote Reference Layer
•The Transport Layer

The following diagram shows the RMI Architecture:
The Stub/Skeleton Layer
This layer intercepts method calls made by the client to the interface reference and redirects these
calls to a
remote object. Stubs are specific to the client side, whereas skeletons are found on the server side.

To achieve location transparency, RMI introduces two special kinds of objects known as stubs and
skeletons
that serve as an interface between an application and rest of the RMI system. This Layer’s purpose is
to transfer
data to the Remote Reference Layer via marshalling and unmarshalling. Marshalling refers to the
process of
converting the data or object being transferred into a byte stream and unmarshalling is the reverse -
converting
the stream into an object or data. This conversion is achieved via object serialization.

The Stub/ Skeleton layer of the RMI lies just below the actual application and is based on the proxy
design
pattern. In the RMI use of the proxy pattern, the stub class plays the role of the proxy for the remote
service
implementation. The skeleton is a helper class that is generated by RMI to help the object
communicate with the
stub; it reads the parameters for the method call from the link, makes the call to the remote service
implementation object, accepts the return value and then writes the return value back to the stub.

In short, the proxy pattern forces method calls to occur through a proxy that acts as a surrogate,
delegating all
calls to the actual object in a manner transparent to the original caller.

Stub
The stub is a client-side object that represents (or acts as a proxy for) the remote object. The stub
has the same
interface, or list of methods, as the remote object. However when the client calls a stub method, the
stub
forwards the request via the RMI infrastructure to the remote object (via the skeleton), which
actually executes
it.

Sequence of events performed by the stub:
• Initiates a connection with the remote VM containing the remote object
• Marshals (writes and transmits) the parameters to the remote VM.
• Waits for the result of the method invocation.
• Unmarshals (reads) the return value or exception returned.
• Return the value to the caller

In the remote VM, each remote object may have a corresponding skeleton.

Skeleton
On the server side, the skeleton object takes care of all the details of “remoteness” so that the
actual remote
object does not need to worry about them. In other words we can pretty much code a remote object
the same
way as if it were local; the skeleton insulates the remote object from the RMI infrastructure.

Sequence of events performed by the skeleton:
• Unmarshals (reads) the parameters for the remote method (remember that these were marshaled
by the stub
  on the client side)
• Invokes the method on the actual remote object implementation.
• Marshals (writes and transmits) the result (return value or exception) to the caller (which is then
  unmarshalled by the stub)

The Remote Reference Layer
The remote reference layer defines and supports the invocation semantics of the RMI connection.
This layer
maintains the session during the method call.

The Transport Layer
The Transport layer makes the stream-based network connections over TCP/IP between the JVMs,
and is
responsible for setting and managing those connections. Even if two JVMs are running on the same
physical

computer, they connect through their host computers TCP/IP network protocol stack. RMI uses a
protocol
called JRMP (Java Remote Method Protocol) on top of TCP/IP (an analogy is HTTP over TCP/IP).

From the JDK 1.2 the JRMP protocol was modified to eliminate the need for skeletons and instead
use
reflection to make connections to the remote services objects. Thus we only need to generate stub
classes in
system implementation compatible with jdk 1.2 and above. To generate stubs we use the Version
1.2 option
with rmic.

The RMI transport layer is designed to make a connection between clients and server, even in the
face of
networking obstacles. The transport layer in the current RMI implementation is TCP-based, but again
a UDPbased
transport layer could be substituted in a different implementation.

       Send to friend
       Permalink
       Add a comment

RMI Architecture 1 of 1

1


www.geekmantra.com, All rights reserved.This website is published by a member of the
GeekMantra Group.
Parameter Passing in Remote Methods Server Object
Activation:-
In the preceding sample programs, we used a server program to instantiate and register
objects so that clients could make remote calls on them. However, in some cases, it may be
wasteful to instantiate lots of server objects and have them wait for connections, whether or
not client objects use them. The activation mechanism lets you delay the object construction
so that a server object is only constructed when at least one client invokes a remote method
on it.

To take advantage of activation, the client code is completely unchanged. The client simply
requests a remote reference and makes calls through it.

However, the server program is replaced by an activation program that constructs activation
descriptors of the objects that are to be constructed at a later time, and binds receivers for
remote method calls with the naming service. When a call is made for the first time, the
information in the activation descriptor is used to construct the object.

A server object that is used in this way should extend the Activatable class and, of course,
implement one or more remote interfaces. For example,

 class ProductImpl
   extends Activatable
   implements Product
 {



1 class ProductImpl
2 extends Activatable
3 implements Product
4{
5 ...
6}



Because the object construction is delayed until a later time, it must happen in a standardized
form. Therefore, you must provide a constructor that takes two parameters:

       An activation ID (which you simply pass to the superclass constructor)
       A single object containing all construction information, wrapped in a
        MarshalledObject

If you need multiple construction parameters, you must package them in a single object. You
can always use an Object[] array or an ArrayList. As you will soon see, you place a
serialized (or marshalled) copy of the construction information inside the activation
descriptor. Your server object constructor should use the get method of the
MarshalledObject class to deserialize the construction information.
In the case of the ProductImpl class, this procedure is quite simpleonly one piece of
information is necessary for construction, namely, the product name. That information can be
wrapped into a MarshalledObject and unwrapped in the constructor:

 public ProductImpl(ActivationID i
 {
   super(id, 0);
   name = (String) data.get();;



1 public ProductImpl(ActivationID id, MarshalledObject data)
2{
3 super(id, 0);
4 name = (String) data.get();;
5 System.out.println("Constructed " + name);
6}



By passing 0 as the second parameter of the superclass constructor, we indicate that the RMI
library should assign a suitable port number to the listener port.

This constructor prints a message so that you can see that the product objects are activated on
demand

Now let us turn to the activation program. First, you need to define an activation group. An
activation group describes common parameters for launching the virtual machine that
contains the server objects. The most important parameter is the security policy.

As with our other server objects, we do not check for security. (Presumably, the objects come
from a trusted source.) However, the virtual machine in which the activated objects run has a
security manager installed. To enable all permissions, supply a file server.policy with the
following contents:

 grant
 {
    permission java.security.AllPe
 };



1 grant
2{
3 permission java.security.AllPermission;
4 };



Construct an activation group descriptor as follows:
 Properties props = new Propert
 props.put("java.security.policy"
 ActivationGroupDesc group = n




1 Properties props = new Properties();
2 props.put("java.security.policy", "/server/server.policy");
3 ActivationGroupDesc group = new ActivationGroupDesc(props, null);



The second parameter describes special command options; we don’t need any for this
example, so we pass a null reference.

Next, create a group ID with the call

 ActivationGroupID id = Activatio




1 ActivationGroupID id = ActivationGroup.getSystem().registerGroup(group);



Now you are ready to construct the activation descriptors. For each object that should be
constructed on demand, you need the following:

       The activation group ID for the virtual machine in which the object should be
        constructed;
       The name of the class (such as "ProductImpl" or "com.mycompany.MyClassImpl");
       The URL string from which to load the class files. This should be the base URL, not
        including package paths;
       The marshalled construction information

        Java IDL and CCRA:-

        IDL:-

he Java IDL API, introduced in Version 1.2 of the Java 2 platform, provides an interface
between Java programs and distributed objects and services built using the Common Object
Request Broker Architecture (CORBA). CORBA is a standard defined by the Object
Management Group (OMG). It describes an architecture, interfaces, and protocols that
distributed objects can use to interact with each other. Part of the CORBA standard is the
Interface Definition Language (IDL), which is an implementation-independent language for
describing the interfaces of remote-capable objects. There are standard mappings defined by
the OMG for converting IDL interfaces into C++ classes, C code, and Java classes, among
other things. These generated classes use the underlying CORBA framework to communicate
with remote clients and give you the basis for implementing and exporting your own
distributed objects. Java IDL is an implementation of the standard IDL-to-Java mapping and
is provided by Sun with the standard Java SDK in the org.omg.CORBA and
org.omg.CosNaming packages and their subpackages.[1]

[1]The version of Java IDL shipped with Version 1.2 of Java 2 is compliant with the CORBA
2.x specification.

Like RMI, Java IDL gives you a way to access remote objects over the network. It also
provides the tools you need to make your objects accessible to other CORBA clients. If you
export a Java class using Java IDL, you can create an instance of that class and publish it
through a naming/directory service. A remote client can find this object, call methods on it,
and receive data from it, just as if it were running on the client's local machine. Unlike RMI,
however, objects that are exported using CORBA can be accessed by clients implemented in
any language with an IDL binding (C, C++, Ada, etc.).

The CORBA standard is extensive, to say the least. In addition to the basic remote object
architecture and the syntax of IDL, it also includes specifications for several distributed
object services, like an object naming service, a security policy service, and persistent object
services. It would be foolhardy to attempt to cover all these topics completely in one chapter,
so I won't. Instead, I'll just cover the basic features of the CORBA architecture and the IDL
syntax. We'll also look at the Naming Service, which is key to almost every CORBA
application because it provides a standard way to find remote CORBA objects on the
network. With that under our belts, we'll take a look at the Java IDL API and the idltojava
compiler and how together they give you an interface from your Java code to CORBA
objects and services. They also give you the tools you need to create your own CORBA
objects, implemented in Java.

The rest of this chapter is broken down roughly into three parts. In the first part, we'll look at
an overview of the CORBA architecture and how it allows you to create, export, access, and
manage remote objects. In the second part, we'll explore the details of creating your own
CORBA objects. Finally, we'll look at how clients can remotely access your CORBA objects.

4.1. The CORBA Architecture
At its core, the CORBA architecture for distributed objects shares many features with the
architecture used by Java RMI. A description of a remote object is used to generate a client
stub interface and a server skeleton interface for the object. A client application invokes
methods on a remote object using the client stub. The method request is transmitted through
the underlying infrastructure to the remote host, where the server skeleton for the object is
asked to invoke the method on the object itself. Any data resulting from the method call
(return values, exceptions) is transmitted back to the client by the communication
infrastructure.

But that's where the similarities between CORBA and RMI end. CORBA was designed from
the start to be a language-independent distributed object standard, so it is much more
extensive and detailed in its specification than RMI is (or needs to be). For the most part,
these extra details are required in CORBA because it needs to support languages that have
different built-in features. Some languages, like C++, directly support objects, while others,
like C, don't. The CORBA standard needs to include a detailed specification of an object
model so that nonobject-oriented languages can take advantage of CORBA. Java includes
built-in support for communicating object interfaces and examining them abstractly (using
Java bytecodes and the Java Reflection API). Many other languages do not. So the CORBA
specification includes details about a Dynamic Invocation Interface and a Dynamic Skeleton
Interface, which can be implemented in languages that don't have their own facilities for
these operations. In languages that do have these capabilities, like Java, there needs to be a
mapping between the built-in features and the features as defined by the CORBA
specification.

The rest of this section provides an overview of the major components that make up the
CORBA architecture: the Interface Definition Language, which is how CORBA interfaces
are defined; the Object Request Broker (ORB), which is responsible for handling all
interactions between remote objects and the applications that use them; the Naming Service, a
standard service in CORBA that lets remote clients find remote objects on the network; and
the inter-ORB communication that handles the low-level communication between processes
in a CORBA context.

4.1.1. Interface Definition Language

The Interface Definition Language provides the primary way of describing data types in
CORBA. IDL is independent of any particular programming language. Mappings, or
bindings, from IDL to specific programming languages are defined and standardized as part
of the CORBA specification. At the time of this writing, standard bindings for C, C++,
Smalltalk, Ada, COBOL, and Java have been approved by the OMG. Chapter 10, "IDL
Reference", contains a complete description of IDL syntax.

The central CORBA functions, services, and facilities, such as the ORB and the Naming
Service, are also specified in IDL. This means that a particular language binding also
provides the bindings for the core CORBA functions to that language. Sun's Java IDL API
follows the Java IDL mapping defined by the OMG. This allows you to run your CORBA-
based Java code in any compliant Java implementation of the CORBA standard, provided
you stick to standard elements of the Java binding. Note, however, that Sun's implementation
includes some nonstandard elements; they are highlighted in this chapter where appropriate.

4.1.2. Object Request Broker

The core of the CORBA architecture is the Object Request Broker, as shown in Figure 4-1.
Each machine involved in a CORBA application must have an ORB running in order for
processes on that machine to interact with CORBA objects running in remote processes.
Object clients and servers make requests through their ORBs; the ORB is responsible for
making the requests happen or indicating why they cannot. The client ORB provides a stub
for a remote object. Requests made on the stub are transferred from the client's ORB to the
ORB servicing the implementation of the target object. The request is passed onto the
implementation through its skeleton interface.
Figure 4-1. Basic CORBA architecture

4.1.3. The Naming Service

The CORBA Naming Service provides a directory naming structure for remote objects. The
tree always starts with a root node, and subnodes of the object tree can be defined. Actual
objects are stored by name at the leaves of the tree. Figure 4-2 depicts an example set of
objects[2] registered within a Naming Service directory. The fully qualified name of an
object in the directory is the ordered list of all of its parent nodes, starting from the root node
and including the leaf name of the object itself. So, the full name of the object labeled "Fred"
is "living thing," "animal," "man," "Fred," in that order.

[2]Example adapted from Categories, by Aristotle. Please pardon the categorization "man,"
as opposed to "human." This is the typical translation of Aristotle's original Greek, perhaps
because political correctness wasn't in fashion in 350 B.C.




Figure 4-2. A naming directory

Each branch in the directory tree is called a naming context, and leaf objects have bindings to
specific names. The org.omg.CosNaming.NamingContext interface represents each branch
in the naming directory. Each NamingContext can be asked to find an object within its
branch of the tree by giving its name relative to that naming context. You can get a reference
to the root context of the naming directory from an ORB using the
resolve_initial_references() method. The standard name for the Naming Service is
"NameService", so the following code snippet gets the root NamingContext:

ORB myORB = ORB.init(...);
org.omg.CORBA.Object nameRef =
        myORB.resolve_initial_references("NameService");
NamingContext nc = NamingContextHelper.narrow(nameRef);

Note that we have to narrow the Object reference to a NamingContext reference using the
NamingContextHelper.narrow() method. Even though Java has a cast operation in its
syntax, there's no guarantee in the Java IDL binding that the object reference returned by the
resolve_initial_references() method is the correct type, since there's no guarantee that
the local environment has access to the language-specific definition of the object's interface.

This narrow() operation highlights one of the key differences between RMI and CORBA. In
the Java environment, class bytecodes are portable, and all remote object types are objects
that can be specified by their full class names. An RMI client can automatically download the
bytecodes for a remote stub from the object server, if the class for the stub cannot be found
locally (see Chapter 3, Remote Method Invocation, for more details on the mechanics of
remote class loading). CORBA is a language-independent remote object scheme, so there is
no portable way to specify a remote object's type when a client obtains a stub reference. As a
result, the stub reference is initially represented by a basic ObjectImpl object that knows
how to forward methods requests to its server object. The client application is forced to "cast"
this stub to the correct local type, using the appropriate narrow() method. In the Java
mapping of IDL, this means calling the narrow() method on the corresponding helper class.
The narrow() method converts the reference, making a type-specific stub interface that also
includes the remote object reference information needed to forward method requests to the
actual object implementation.

4.1.4. Inter-ORB Communication

Version 2.0 (and later) of the CORBA standard includes specifications for inter-ORB
communication protocols that can transmit object requests between various ORBs running on
the network. The protocols are independent of the particular ORB implementations running at
either end of the communication link. An ORB implemented in Java can talk to another ORB
implemented in C, as long as they're both compliant with the CORBA standard and use a
standard communication protocol. The inter-ORB protocol is responsible for delivering
messages between two cooperating ORBs. These messages might be method requests, return
types, error messages, etc. The inter-ORB protocol also deals with differences between the
two ORB implementations, like machine-level byte ordering and alignment. As a CORBA
application developer, you shouldn't have to deal directly with the low-level communication
protocol between ORBs. If you want two ORBs to talk to each other, you just need to be sure
that they both speak a common, standard inter-ORB protocol.

The Internet Inter-ORB Protocol (IIOP) is an inter-ORB protocol based on TCP/IP. TCP/IP is
by far the most commonly used network protocol on the Internet, so IIOP is the most
commonly used CORBA communication protocol. There are other standard CORBA
protocols defined for other network environments, however. The DCE Common Inter-ORB
Protocol (DCE-CIOP), for example, allows ORBs to communicate on top of DCE-RPC.

CCRA:-

Remote Method Calls with SOAP:-


Remote procedure calls in SOAP
Remote procedure calls in SOAP are essentially client-server interactions over HTTP where the
request and response comply with SOAP encoding rules. The Request-URI (Universal Resource
Identifier) in HTTP is typically used at the server end to map to a class or an object, but this is not
mandated by SOAP. Additionally, the HTTP header SOAPAction specifies the interface name (a URI)
and the name of the method to be called on the server. The SOAP message is an XML document
whose root element, the Envelope, specifies the overall structure of the message, its intended
recipient, and other attributes of the message. SOAP specifies a remote procedure call convention,
which includes the representation and format to be used for calls and responses. A method call is
modeled as a compound data element consisting of a sequence of fields (accessors), one for each
parameter. A return structure consists of the return value as well as the out and in/out parameters.
SOAP encoding rules specify the serialization for primitive and application-defined datatypes.

Figures 1 and 2 show the request and response structure of a remote procedure call
transported as an HTTP request carrying a SOAP payload.




                         Figure 1: Example of a SOAP request sent via HTTP.


         POST /Temperature HTTP/1.1
         Host: www.temperature-service.com
         Content-Type: text/xml
         Content-Length: 357
         SOAPAction: "http://weather.org/query#GetTemperature"

         < SOAP-ENV:Envelope
            xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
            SOAP-
         ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
           < SOAP-ENV:Body>
             < m:GetTemperature xmlns:m="http://weather.org/query">
                < longitude>39W< /longitude>
                < latitude>62S< /latitude>
             < /m:GetTemperature>
           < /SOAP-ENV:Body>
         < /SOAP-ENV:Envelope>
                     Figure 2: Example of a SOAP response received via HTTP.


        HTTP/1.1 200 OK
        Content-Type: text/xml
        Content-Length: 343

        < SOAP-ENV:Envelope
           xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
           SOAP-
        ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
          < SOAP-ENV:Body>
            < m:GetTemperatureResponse
        xmlns:m="http://weather.org/query">
              < centigrade>28.4< /centigrade>
            < /m:GetTemperatureResponse>
          < /SOAP-ENV:Body>
        < /SOAP-ENV:Envelope>



SOAP allows hierarchically structured queries and responses, and specifies serialization of
primitive string, numeric and date datatypes, and aggregates like arrays and vectors. Sparse
arrays, and protocols for sending parts of them are also supported. New types may be defined
using the <complexType> construct inside a schema definition.

Overall, SOAP provides many advantages. Unfortunately, its universality comes with a
performance penalty: XML messages are textual and so the sizes of its messages are
significantly larger than protocols which send binary data. Since a distinguishing
characteristic of scientific computation is the need to handle large data sets, the performance
of SOAP relative to specialized protocols that can use binary representations is an important
issue. The next section tests SOAP performance relative to other communication protocols
                       SECTION-C
       Topics covered in this section:-
       SWING
             Lists,
             Trees, Tables,
             Styled Text Components,
             Progress Indicators,
             Component Organizers

       AWT
             The Rendering Pipeline,
             Shapes, Areas,
             Strokes,
             Paint,
             Coordinate Transformations,
             Clipping,
             Transparency and Composition,
             Rendering Hints,
             Readers and Writers for Images,
             Image Manipulation,
             Printing. TheClipboard,
             Drag and Drop

                                SWING
Java Swings Tutorial

What is Swings in java ?

      A part of The JFC
      Swing Java consists of
       Look and feel
       Accessibility
       Java 2D
       Drag and Drop, etc

      Compiling & running programs

       ‘javac <program.java>’ && ‘java <program>’
       Or JCreator / IDE
      if you do not explicitly add a GUI component to a container, the GUI component will
       not be displayed when the container appears on the screen.

       Swing, which is an extension library to the AWT, includes new and improved
       components that enhance the look and functionality of GUIs. Swing can be used to
       build Standalone swing gui Apps as well as Servlets and Applets. It employs a
       model/view design architecture. Swing is more portable and more flexible than AWT.

Swing Model/view design: The “view part” of the MV design is implemented with a
component object and the UI object. The “model part” of the MV design is implemented by a
model object and a change listener object.

Swing is built on top of AWT and is entirely written in Java, using AWT’s lightweight
component support. In particular, unlike AWT, t he architecture of Swing components makes
it easy to customize both their appearance and behavior. Components from AWT and Swing
can be mixed, allowing you to add Swing support to existing AWT-based programs. For
example, swing components such as JSlider, JButton and JCheckbox could be used in the
same program with standard AWT labels, textfields and scrollbars. You could subclass the
existing Swing UI, model, or change listener classes without having to reinvent the entire
implementation. Swing also has the ability to replace these objects on-the-fly.

      100% Java implementation of components
      Pluggable Look & Feel
      Lightweight components
      Uses MVC Architecture
       Model represents the data
       View as a visual representation of the data
       Controller takes input and translates it to changes in data
      Three parts
       Component set (subclasses of JComponent)
       Support classes
       Interfaces


In Swing, classes that represent GUI components have names beginning with the letter J.
Some examples are JButton, JLabel, and JSlider. Altogether there are more than 250 new
classes and 75 interfaces in Swing — twice as many as in AWT.

Java Swing class hierarchy

The class JComponent, descended directly from Container, is the root class for most of
Swing’s user interface components.
Swing contains components that you’ll use to build a GUI. I am listing you some of the
commonly used Swing components. To learn and understand these swing programs, AWT
Programming knowledge is not required.

Java Swing Examples

Below is a java swing code for the traditional Hello World program.

Basically, the idea behind this Hello World program is to learn how to create a java program,
compile and run it. To create your java source code you can use any editor( Text pad/Edit
plus are my favorites) or you can use an IDE like Eclipse.

import javax.swing.JFrame;
import javax.swing.JLabel;

//import statements
//Check if window closes automatically. Otherwise add suitable code
public class HelloWorldFrame extends JFrame {

         public static void main(String args[]) {
                 new HelloWorldFrame();
         }
         HelloWorldFrame() {
                 JLabel jlbHelloWorld = new JLabel("Hello World");
                 add(jlbHelloWorld);
                 this.setSize(100, 100);
                 // pack();
                 setVisible(true);
         }
}


Output
Note: Below are some links to java swing tutorials that forms a helping hand to get started
with java programming swing.




      JPanel is Swing’s version of the AWT class Panel and uses the same default layout,
       FlowLayout. JPanel is descended directly from JComponent.
      JFrame is Swing’s version of Frame and is descended directly from that class. The
       components added to the frame are referred to as its contents; these are managed by the
       contentPane. To add a component to a JFrame, we must use its contentPane instead.
      JInternalFrame is confined to a visible area of a container it is placed in. It can be iconified ,
       maximized and layered.
      JWindow is Swing’s version of Window and is descended directly from that class. Like
       Window, it uses BorderLayout by default.
      JDialog is Swing’s version of Dialog and is descended directly from that class. Like Dialog, it
       uses BorderLayout by default. Like JFrame and JWindow,
       JDialog contains a rootPane hierarchy including a contentPane, and it allows layered and
       glass panes. All dialogs are modal, which means the current
       thread is blocked until user interaction with it has been completed. JDialog class is intended
       as the basis for creating custom dialogs; however, some
       of the most common dialogs are provided through static methods in the class JOptionPane.
      JLabel, descended from JComponent, is used to create text labels.
      The abstract class AbstractButton extends class JComponent and provides a foundation for a
       family of button classes, including

       JButton.

      JTextField allows editing of a single line of text. New features include the ability to justify the
       text left, right, or center, and to set the text’s font.
      JPasswordField (a direct subclass of JTextField) you can suppress the display of input. Each
       character entered can be replaced by an echo character.
       This allows confidential input for passwords, for example. By default, the echo character is
       the asterisk, *.
      JTextArea allows editing of multiple lines of text. JTextArea can be used in conjunction with
       class JScrollPane to achieve scrolling. The underlying JScrollPane can be forced to always or
       never have either the vertical or horizontal scrollbar;
       JButton is a component the user clicks to trigger a specific action.
      JRadioButton is similar to JCheckbox, except for the default icon for each class. A set of radio
       buttons can be associated as a group in which only
       one button at a time can be selected.
      JCheckBox is not a member of a checkbox group. A checkbox can be selected and
       deselected, and it also displays its current state.
      JComboBox is like a drop down box. You can click a drop-down arrow and select an option
       from a list. For example, when the component has focus,
       pressing a key that corresponds to the first character in some entry’s name selects that
       entry. A vertical scrollbar is used for longer lists.
      JList provides a scrollable set of items from which one or more may be selected. JList can be
       populated from an Array or Vector. JList does not
       support scrolling directly, instead, the list must be associated with a scrollpane. The view
       port used by the scroll pane can also have a user-defined
       border. JList actions are handled using ListSelectionListener.
      JTabbedPane contains a tab that can have a tool tip and a mnemonic, and it can display both
       text and an image.
      JToolbar contains a number of components whose type is usually some kind of button which
       can also include separators to group related components
       within the toolbar.
      FlowLayout when used arranges swing components from left to right until there’s no more
       space available. Then it begins a new row below it and moves
       from left to right again. Each component in a FlowLayout gets as much space as it needs and
       no more.
      BorderLayout places swing components in the North, South, East, West and center of a
       container. You can add horizontal and vertical gaps between
       the areas.
      GridLayout is a layout manager that lays out a container’s components in a rectangular grid.
       The container is divided into equal-sized rectangles,
       and one component is placed in each rectangle.
      GridBagLayout is a layout manager that lays out a container’s components in a grid of cells
       with each component occupying one or more cells,
       called its display area. The display area aligns components vertically and horizontally,
       without requiring that the components be of the same size.
      JMenubar can contain several JMenu’s. Each of the JMenu’s can contain a series of
       JMenuItem ‘s that you can select. Swing provides support for
       pull-down and popup menus.
      Scrollable JPopupMenu is a scrollable popup menu that can be used whenever we have so
       many items in a popup menu that exceeds the screen visible height.

       Java Swing Projects

      Java Swing Calculator developed using Java Swing. It is a basic four-function calculator java
       program source code.
      Java Swing Address Book demonstrates how to create a simple free address book program
       using java swing and jdbc. Also you will learn to use
       the following swing components like Jbuttons, JFrames, JTextFields and Layout Manager
       (GridBagLayout).




Create a JList Component in Java

In this section, you will learn how to create a JList component of swing. JList is a component
of GUI. It provides the multiple items in a list and some times it shows the data in multiple
columns in a list. Lists are used to select item from the item's group like combo box but the
major difference between list and the combo box is that you can select only one item from the
combo box since you can select more than one item at once from the list. You can easily add
or remove items from or to the JList component of swing. The JList component has been
shown in this article below:




This program provides a List. The given List has multiple subjects as items like: Math,
Computer, Physics and Chemistry.

JList:
This is the class which is used to create a list which contains items. This class extends the
JComponent class in java swing. There has been using string array values in this program.

Here is the code of program:

import javax.swing.*;

public class CreateJList{
  public static void main(String[] args) {
  String subject[] = {"Math", "Computer", "Phisics", "Chemestry"};
  JFrame frame = new JFrame("Creating a JList Component");
  JPanel panel = new JPanel();
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JList list = new JList(subject);
  frame.setUndecorated(true);
  frame.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
  panel.add(list);
  frame.add(panel);
  frame.setSize(400,400);
  frame.setVisible(true);
  }
}



        TREE:-

1. Introduction: Custom Models and Renderers
The idea of custom data models and cell renderers was covered in detail in the Swing tutorial section
on JList. JTree is another component that commonly uses these techniques. This section will
illustrate the basic use of JTree, show how to respond to node selection events, give an example of
a custom model (a tree that builds the children "on the fly") and show how replace the icons that
appear at the tree nodes.


2. Simple JTree
The simplest and most common way to use JTree is to create objects of type
DefaultMutableTreeNode to act as the nodes of the tree. Nodes that have no children will be
displayed as leaves. You supply a value, known as the "user object", to the
DefaultMutableTreeNode constructor, to act as the value at each node. The toString method
of that user object is what is displayed for each node.

Once you have some nodes, you hook them together in a tree structure via
parentNode.add(childNode). Finally, you pass the node to the JTree constructor. Note
that, since trees can change size based upon user input (expanding and collapsing nodes),
trees are usually placed inside a JScrollPane. For example, here is a very simple tree:

DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode child1 = new DefaultMutableTreeNode("Child 1");
root.add(child1);
DefaultMutableTreeNode child2 = new DefaultMutableTreeNode("Child 2");
root.add(child2);
JTree tree = new JTree(root);
someWindow.add(new JScrollPane(tree));
For more complicated trees, it is sometimes tedious and hard to maintain if you hook everything
together "by hand". So you may find it useful to first make a simple tree-like data structure, then
build nodes and hook them together automatically from that data structure. Here's an example that
uses nested arrays to define the data structure.

2.1 Simple JTree Example: Source Code (Download source code)
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

public class SimpleTree extends JFrame {
  public static void main(String[] args) {
    new SimpleTree();
  }

  public SimpleTree() {
    super("Creating a Simple JTree");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    Object[] hierarchy =
      { "javax.swing",
        "javax.swing.border",
        "javax.swing.colorchooser",
        "javax.swing.event",
        "javax.swing.filechooser",
        new Object[] { "javax.swing.plaf",
                        "javax.swing.plaf.basic",
                        "javax.swing.plaf.metal",
                        "javax.swing.plaf.multi" },
            "javax.swing.table",
            new Object[] { "javax.swing.text",
                           new Object[] { "javax.swing.text.html",
                                          "javax.swing.text.html.parser" },
                           "javax.swing.text.rtf" },
            "javax.swing.tree",
            "javax.swing.undo" };
        DefaultMutableTreeNode root = processHierarchy(hierarchy);
        JTree tree = new JTree(root);
        content.add(new JScrollPane(tree), BorderLayout.CENTER);
        setSize(275, 300);
        setVisible(true);
    }

    /**   Small routine that will make node out of the first entry
     *    in the array, then make nodes out of subsequent entries
     *    and make them child nodes of the first one. The process is
     *    repeated recursively for entries that are arrays.
     */

    private DefaultMutableTreeNode processHierarchy(Object[] hierarchy) {
      DefaultMutableTreeNode node =
        new DefaultMutableTreeNode(hierarchy[0]);
      DefaultMutableTreeNode child;
      for(int i=1; i<hierarchy.length; i++) {
        Object nodeSpecifier = hierarchy[i];
        if (nodeSpecifier instanceof Object[]) // Ie node with children
          child = processHierarchy((Object[])nodeSpecifier);
        else
          child = new DefaultMutableTreeNode(nodeSpecifier); // Ie Leaf
        node.add(child);
      }
      return(node);
    }
}
Note: also requires WindowUtilities.java and ExitListener.java, shown earlier.

2.2. Simple JTree Example: Initial Result
2.2. Simple JTree Example: Expanded Result




3. Handling JTree Events
To handle selection events, attach a TreeSelectionListener. The TreeSelectionListener
interface requires a single method; valueChanged. You extract the currently selected node via
tree.getLastSelectedPathComponent, then casting that to your node type (usually
DefaultMutableTreeNode), then extracting the user object via getUserObject. However, if all
you want is the node label, you can just call toString on the result of
tree.getLastSelectedPathComponent. Here's an example:


3.1 JTree with Selectable Nodes: Source Code (Download source code)
import   java.awt.*;
import   javax.swing.*;
import   javax.swing.tree.*;
import   javax.swing.event.*;

public class SelectableTree extends JFrame
                            implements TreeSelectionListener {
  public static void main(String[] args) {
    new SelectableTree();
  }

  private JTree tree;
  private JTextField currentSelectionField;

  public SelectableTree() {
    super("JTree Selections");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    DefaultMutableTreeNode root =
      new DefaultMutableTreeNode("Root");
    DefaultMutableTreeNode child;
        DefaultMutableTreeNode grandChild;
        for(int childIndex=1; childIndex<4; childIndex++) {
          child = new DefaultMutableTreeNode("Child " + childIndex);
          root.add(child);
          for(int grandChildIndex=1; grandChildIndex<4; grandChildIndex++) {
            grandChild =
              new DefaultMutableTreeNode("Grandchild " + childIndex +
                                         "." + grandChildIndex);
            child.add(grandChild);
          }
        }
        tree = new JTree(root);
        tree.addTreeSelectionListener(this);
        content.add(new JScrollPane(tree), BorderLayout.CENTER);
        currentSelectionField = new JTextField("Current Selection: NONE");
        content.add(currentSelectionField, BorderLayout.SOUTH);
        setSize(250, 275);
        setVisible(true);
    }

    public void valueChanged(TreeSelectionEvent event) {
      currentSelectionField.setText
        ("Current Selection: " +
         tree.getLastSelectedPathComponent().toString());
    }
}
Note: also requires WindowUtilities.java and ExitListener.java, shown earlier.

3.2. Selectable JTree Example: Initial Result




3.3. Selectable JTree Example: Result after Expanding Tree and Selecting
Node
4. Custom Models and Dynamic Trees
A JTree uses a TreeModel to get its data. As with JList, you can replace the model altogether,
specifying how to extract data from the custom model. See the tutorial section on JList for an
example of this general approach.

In the case of JTree, however, the default TreeModel uses a TreeNode to store data
associated with the tree, and it is more common to leave the TreeModel unchanged and
instead make a custom TreeNode. The easiest approach for that is to start with
DefaultMutableTreeNode. One of the common cases where this is useful is when you don't
want to explicitly lay out each node in the tree, but instead you have some sort of algorithm
that describes the children of a given node, and you want to build the tree dynamically, only
actually generating children for places that the user expands. For instance, in the following
example the tree is potentially infinite, with each node describing a section in an outline. The
root will be "1", the first-level children will be 1.1, 1.2, 1.3, etc., the second-level children
will be 1.1.1, 1.1.2, etc., and so forth. The actual number of children of each node will be
determined by a command-line argument to the program.

The key to building a JTree dynamically is to observe that getChildCount (a method in
DefaultMutableTreeNode) will be called before any of the children will actually be
retrieved. So you keep a flag indicating whether children have ever been built. So you wait
until getChildCount is called, then, if the flag is false, build the children and add them. To
keep the tree from trying to count the children (and thus build the nodes) in order to
determine which nodes are leaf nodes, override isLeaf to always return false.

4.1 Dynamic Tree: Example Code (Download source code)
import java.awt.*;
import javax.swing.*;

public class DynamicTree extends JFrame {
  public static void main(String[] args) {
    int n = 5; // Number of children to give each node
    if (args.length > 0)
          try {
            n = Integer.parseInt(args[0]);
          } catch(NumberFormatException nfe) {
            System.out.println("Can't parse number; using default of " + n);
          }
        new DynamicTree(n);
    }

    public DynamicTree(int n) {
      super("Creating a Dynamic JTree");
      WindowUtilities.setNativeLookAndFeel();
      addWindowListener(new ExitListener());
      Container content = getContentPane();
      JTree tree = new JTree(new OutlineNode(1, n));
      content.add(new JScrollPane(tree), BorderLayout.CENTER);
      setSize(300, 475);
      setVisible(true);
    }
}
Note: also requires WindowUtilities.java and ExitListener.java, shown earlier.

4.2 OutlineNode.java (Download source code)
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

public class OutlineNode extends DefaultMutableTreeNode {
  private boolean areChildrenDefined = false;
  private int outlineNum;
  private int numChildren;

    public OutlineNode(int outlineNum, int numChildren) {
      this.outlineNum = outlineNum;
      this.numChildren = numChildren;
    }

    public boolean isLeaf() {
      return(false);
    }

    public int getChildCount() {
      if (!areChildrenDefined)
        defineChildNodes();
      return(super.getChildCount());
    }

    private void defineChildNodes() {
      // You must set the flag before defining children if you
      // use "add" for the new children. Otherwise you get an infinite
      // recursive loop, since add results in a call to getChildCount.
      // However, you could use "insert" in such a case.
      areChildrenDefined = true;
      for(int i=0; i<numChildren; i++)
        add(new OutlineNode(i+1, numChildren));
    }

    public String toString() {
      TreeNode parent = getParent();
      if (parent == null)
          return(String.valueOf(outlineNum));
        else
          return(parent.toString() + "." + outlineNum);
    }
}

4.3. Dynamic Tree: Initial Result




4.4. Dynamic Tree: Result After Expanding A Few Nodes
5. Replacing the Icons at the Tree Nodes
Defining a custom method of drawing a node in a JTree is little different than it was for a JList. See
the tutorial section on JList for an example of this general approach. However, one very common
task is to simply to change the three icons shown to indicate unexpanded internal (ie non-leaf)
nodes, expanded internal nodes, and leaf nodes. This is quite simple -- just make a
DefaultTreeCellRenderer, call setOpenIcon, setClosedIcon, and setLeafIcon either
with the Icon of interest (usually an ImageIcon made from a small image file) or null to just turn
off node icons. Then associate this cell renderer with the tree via setCellRenderer.

5.1 Replacing the Icons: Example Code (Download source code)
import   java.awt.*;
import   java.awt.event.*;
import   javax.swing.*;
import   javax.swing.tree.*;

/** JTree with missing or custom icons at the tree nodes.
 * 1999 Marty Hall, http://www.apl.jhu.edu/~hall/java/
 */

public class CustomIcons extends JFrame {
  public static void main(String[] args) {
    new CustomIcons();
    }

    private Icon customOpenIcon = new ImageIcon("images/Circle_1.gif");
    private Icon customClosedIcon = new ImageIcon("images/Circle_2.gif");
    private Icon customLeafIcon = new ImageIcon("images/Circle_3.gif");

    public CustomIcons() {
      super("JTree Selections");
      WindowUtilities.setNativeLookAndFeel();
      addWindowListener(new ExitListener());
      Container content = getContentPane();
      content.setLayout(new FlowLayout());
      DefaultMutableTreeNode root =
        new DefaultMutableTreeNode("Root");
      DefaultMutableTreeNode child;
      DefaultMutableTreeNode grandChild;
      for(int childIndex=1; childIndex<4; childIndex++) {
        child = new DefaultMutableTreeNode("Child " + childIndex);
        root.add(child);
        for(int grandChildIndex=1; grandChildIndex<4; grandChildIndex++) {
          grandChild =
            new DefaultMutableTreeNode("Grandchild " + childIndex +
                                       "." + grandChildIndex);
          child.add(grandChild);
        }
      }

        JTree tree1 = new JTree(root);
        tree1.expandRow(1); // Expand children to illustrate leaf icons
        JScrollPane pane1 = new JScrollPane(tree1);
        pane1.setBorder(BorderFactory.createTitledBorder("Standard Icons"));
        content.add(pane1);

        JTree tree2 = new JTree(root);
        tree2.expandRow(2); // Expand children to illustrate leaf icons
        DefaultTreeCellRenderer renderer2 = new DefaultTreeCellRenderer();
        renderer2.setOpenIcon(null);
        renderer2.setClosedIcon(null);
        renderer2.setLeafIcon(null);
        tree2.setCellRenderer(renderer2);
        JScrollPane pane2 = new JScrollPane(tree2);
        pane2.setBorder(BorderFactory.createTitledBorder("No Icons"));
        content.add(pane2);

        JTree tree3 = new JTree(root);
        tree3.expandRow(3); // Expand children to illustrate leaf icons
        DefaultTreeCellRenderer renderer3 = new DefaultTreeCellRenderer();
        renderer3.setOpenIcon(customOpenIcon);
        renderer3.setClosedIcon(customClosedIcon);
        renderer3.setLeafIcon(customLeafIcon);
        tree3.setCellRenderer(renderer3);
        JScrollPane pane3 = new JScrollPane(tree3);
        pane3.setBorder(BorderFactory.createTitledBorder("Custom Icons"));
        content.add(pane3);

        pack();
        setVisible(true);
    }
}
Note: also requires WindowUtilities.java and ExitListener.java, shown earlier.
5.2. Replacing the Icons: Result




       This page is part of my Quick Swing Tutorial for AWT Programmers. © 1999 Marty Hall. All
       source code freely available for unrestricted use. Created for for work in the Research and
       Technology Development Center of the Johns Hopkins University Applied Physics Lab, for
       courses in the Johns Hopkins Part-Time MS Program in Computer Science, and for various
       industry seminars and Java short courses.

       STYLE TEXT COMPONENT:-


Using Text Components
This section provides background information you might need when using Swing text
components. If you intend to use an unstyled text component — a text field, password field,
formatted text field, or text area — go to its how-to page and return here only if necessary. If
you intend to use a styled text component, see How to Use Editor Panes and Text Panes, and
read this section as well. If you do not know which component you need, read on.

Swing text components display text and optionally allow the user to edit the text. Programs
need text components for tasks ranging from the straightforward (enter a word and press
Enter) to the complex (display and edit styled text with embedded images in an Asian
language).

Swing provides six text components, along with supporting classes and interfaces that meet
even the most complex text requirements. In spite of their different uses and capabilities, all
Swing text components inherit from the same superclass, JTextComponent, which provides a
highly-configurable and powerful foundation for text manipulation.

The following figure shows the JTextComponent hierarchy.




The following picture shows an application called TextSamplerDemo that uses each Swing
text component.




Try this:
   1. Click the Launch button to run TextSamplerDemo using Java™ Web Start (download JDK 6 or
      later). Alternatively, to compile and run the example yourself, consult the example index.

   2. Type some text in the text field and press Enter. Do the same in the password field. The label
      beneath the fields is updated when you press Enter.
   3. Try entering valid and invalid dates into the formatted text field. Note that when you press
      Enter the label beneath the fields is updated only if the date is valid.
   4. Select and edit text in the text area and the text pane. Use keyboard bindings, Ctrl-X, Ctrl-C,
      and Ctrl-V, to cut, copy, and paste text, respectively.
   5. Try to edit the text in the editor pane, which has been made uneditable with a call to
      setEditable.
   6. Look in the text pane to find an example of an embedded component and an embedded
      icon.




The TextSamplerDemo example uses the text components in very basic ways. The following
table tells you more about what you can do with each kind of text component.

 Group                           Description                                    Swing Classes


           Also known simply as text fields, text controls can
           display only one line of editable text. Like buttons,       JTextField and its subclasses
  Text
           they generate action events. Use them to get a small        JPasswordField and
Controls
           amount of textual information from the user and             JFormattedTextField
           perform an action after the text entry is complete.


           JTextArea can display multiple lines of editable text.
 Plain     Although a text area can display text in any font, all of
 Text      the text is in the same font. Use a text area to allow      JTextArea
 Areas     the user to enter unformatted text of any length or to
           display unformatted help information.


           A styled text component can display editable text
           using more than one font. Some styled text
           components allow embedded images and even
           embedded components. Styled text components are
 Styled    powerful and multi-faceted components suitable for          JEditorPane
  Text     high-end needs, and offer more avenues for                  and its subclass
 Areas     customization than the other text components.               JTextPane


           Because they are so powerful and flexible, styled
           text components typically require more initial
           programming to set up and use. One exception is
           that editor panes can be easily loaded with
           formatted text from a URL, which makes them
           useful for displaying uneditable help information.

This Tutorial provides information about the foundation laid by the JTextComponent class
and tells you how to accomplish some common text-related tasks. Because the
JTextComponent class and its subclasses have too many features to be completely described
in this Tutorial, please visit the Swing & AWT forum at java.net for help and information.



       Progress Indicators:-


Progress Bar in Java Swing




In this section, you can learn how to handle progress bar in java swing. This section shows
you how the progress bar starts and stops with the timer. Through the given example you can
understand how the progress bar is created for showing your work is in progress.

This program shows you a frame in which a button labeled by the string "Start", a progress
bar and another is the label which has been used to display some messages. When you click
on the "Start" button progress bar is started to progress the completed process in percent and
the label which holds the text "Roseindia.net" is change to with the label text "Downloading
is in process......" in green color and the button is disabled. When the value of the progress
bar is become 100% then the label text of the label is changed with the text "Downloading
completed." in red color and "Start" button is enabled.

The label display the information about the Downloading process whether completed or not.
But here, nothing is downloading through the program. This message on the label has been
used only for showing in output of the program. For completion the process, there are some
methods and APIs are used in the program has been explained as follows:

JProgressBar:
This is the class which creates the progress bar using it's constructor JProgressBar() to show
the status of your process completion. The constructor JProgressBar() takes two argument
as parameter in which, first is the initial value of the progress bar which is shown in the
starting and another argument is the counter value by which the value of the progress bar is
incremented. Here, the value of the progress bar is incremented by 20.
setStringPainted(boolean):
This is the method of the JProgressBar class which shows the complete process in percent
on the progress bar. It takes a boolean value as a parameter. If you pass the true then the
value will be seen on the progress bar otherwise not seen.

setValue():
This is the method of the JProgressBar class which sets the value to the progress bar.

Timer():
This the constructor of the Timer class which starts the timer for timing. This constructor
takes two argument as parameter first is the interval (in milliseconds) of the timer and second
one is the listener object. Time is started using the start() method of the Timer class.

Here is the code of the program:

import   java.awt.*;
import   java.awt.event.*;
import   javax.swing.*;
import   javax.swing.text.html.*;

public class SwingProgressBar{
  final static int interval = 1000;
  int i;
  JLabel label;
  JProgressBar pb;
  Timer timer;
  JButton button;

  public SwingProgressBar() {
  JFrame frame = new JFrame("Swing Progress Bar");
  button = new JButton("Start");
  button.addActionListener(new ButtonListener());

  pb = new JProgressBar(0, 20);
  pb.setValue(0);
  pb.setStringPainted(true);

  label = new JLabel("Roseindia.net");

  JPanel panel = new JPanel();
  panel.add(button);
  panel.add(pb);

  JPanel panel1 = new JPanel();
  panel1.setLayout(new BorderLayout());
  panel1.add(panel, BorderLayout.NORTH);
  panel1.add(label, BorderLayout.CENTER);
  panel1.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
  frame.setContentPane(panel1);
  frame.pack();
  frame.setVisible(true);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  //Create a timer.
  timer = new Timer(interval, new ActionListener() {
  public void actionPerformed(ActionEvent evt) {
  if (i == 20){
  Toolkit.getDefaultToolkit().beep();
  timer.stop();
  button.setEnabled(true);
  pb.setValue(0);
  String str = "<html>" + "<font color=\"#FF0000\">" + "<b>" +
"Downloading completed." + "</b>" + "</font>" + "</html>";
  label.setText(str);
  }
  i = i + 1;
  pb.setValue(i);
  }
  });
  }

  class ButtonListener implements ActionListener {
  public void actionPerformed(ActionEvent ae) {
  button.setEnabled(false);
  i = 0;
  String str = "<html>" + "<font color=\"#008000\">" + "<b>" +
"Downloading is in process......." + "</b>" + "</font>" + "</html>";
  label.setText(str);
  timer.start();
  }
  }

    public static void main(String[] args) {
    SwingProgressBar spb = new SwingProgressBar();
    }
}



       Component Organizers:-


Component Organizers
Filed under Computer

0

We conclude the discussion of advanced Swing features with a presentation of components
that help organize other components. These include the split pane, a mechanism for splitting
an area into multiple parts whose boundaries can be adjusted, the tabbed pane, which uses tab
dividers to allow a user to flip through multiple panels, and the desktop pane, which can be
used to implement applications that display multiple internal frames.
Split Panes:-

Split panes split a component into two parts, with an adjustable boundary in between. Figure
shows a frame with two split panes. The outer pane is split vertically, with a text area on the
bottom and another split pane on the top. That pane is split horizontally, with a list on the left
and a label containing an image on the right.




You construct a split pane by specifying the orientation, one of
JSplitPane.HORIZONTAL_SPLIT or JSplitPane.VERTICAL_SPLIT, followed by the two
components. For example,

 JSplitPane innerPane = new JSp




1 JSplitPane innerPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, planetList, planetImage);




That’s all you have to do. If you like, you can add “one-touch expand” icons to the splitter
bar. You see those icons in the top pane in Figure . In the Metal look and feel, they are small
triangles. If you click one of them, the splitter moves all the way in the direction to which the
triangle is pointing, expanding one of the panes completely.

To add this capability, call

 innerPane.setOneTouchExpand
1 innerPane.setOneTouchExpandable(true);




The “continuous layout” feature continuously repaints the contents of both components as the
user adjusts the splitter. That looks classier, but it can be slow. You turn on that feature with
the call

    innerPane.setContinuousLayout




1 innerPane.setContinuousLayout(true);




In the example program, we left the bottom splitter at the default (no continuous layout).
When you drag it, you only move a black outline. When you release the mouse, the
components are repainted.

The straightforward program in Example populates a list box with planets. When the user
makes a selection, the planet image is displayed to the right and a description is placed in the
text area on the bottom. When you run the program, adjust the splitters and try out the one-
touch expansion and continuous layout features.

Example . SplitPaneTest.java
     1. import java.aw t.*;
     2. import java.aw t.event.*;
     3. import java.util.*;
     4. import javax.sw ing.*;




1       1. import java.awt.*;

2       2. import java.awt.event.*;

3       3. import java.util.*;

4       4. import javax.swing.*;

5       5. import javax.swing.event.*;

6       6.

7       7. /**

8       8. This program demonstrates the split pane component
9    9. organizer.

10 10. */

11 11. public class SplitPaneTest

12 12. {

13 13. public static void main(String[] args)

14 14. {

15 15.      JFrame frame = new SplitPaneFrame();

16 16.      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

17 17.      frame.setVisible(true);

18 18. }

19 19. }

20 20.

21 21. /**

22 22. This frame consists of two nested split panes to demonstrate

23 23. planet images and data.

24 24. */

25 25. class SplitPaneFrame extends JFrame

26 26. {

27 27. public SplitPaneFrame()

28 28. {

29 29.      setTitle("SplitPaneTest");

30 30.      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

31 31.

32 32.      // set up components for planet names, images, descriptions

33 33.

34 34.      final JList planetList = new JList(planets);

35 35.      final JLabel planetImage = new JLabel();
36 36.   final JTextArea planetDescription = new JTextArea();

37 37.

38 38.   planetList.addListSelectionListener(new

39 39.    ListSelectionListener()

40 40.    {

41 41.        public void valueChanged(ListSelectionEvent event)

42 42.        {

43 43.            Planet value = (Planet) planetList.getSelectedValue();

44 44.

45 45.            // update image and description

46 46.

47 47.            planetImage.setIcon(value.getImage());

48 48.            planetDescription.setText(value.getDescription());

49 49.        }

50 50.    });

51 51.

52 52.   // set up split panes

53 53.

54 54.   JSplitPane innerPane

55 55.    = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, planetList, planetImage);

56 56.

57 57.   innerPane.setContinuousLayout(true);

58 58.   innerPane.setOneTouchExpandable(true);

59 59.

60 60.   JSplitPane outerPane

61 61.    = new JSplitPane(JSplitPane.VERTICAL_SPLIT, innerPane, planetDescription);

62 62.
63 63.      add(outerPane, BorderLayout.CENTER);

64 64. }

65 65.

66 66. private Planet[] planets =

67 67.      {

68 68.           new Planet("Mercury", 2440, 0),

69 69.           new Planet("Venus", 6052, 0),

70 70.           new Planet("Earth", 6378, 1),

71 71.           new Planet("Mars", 3397, 2),

72 72.           new Planet("Jupiter", 71492, 16),

73 73.           new Planet("Saturn", 60268, 18),

74 74.           new Planet("Uranus", 25559, 17),

75 75.           new Planet("Neptune", 24766, 8),

76 76.           new Planet("Pluto", 1137, 1),

77 77.      };

78 78. private static final int DEFAULT_WIDTH = 300;

79 79. private static final int DEFAULT_HEIGHT = 300;

80 80. }

81 81.

82 82. /**

83 83. Describes a planet.

84 84. */

85 85. class Planet

86 86. {

87 87. /**

88 88.      Constructs a planet.

89 89.      @param n the planet name
90 90.     @param r the planet radius

91 91.     @param m the number of moons

92 92. */

93 93. public Planet(String n, double r, int m)

94 94. {

95 95.     name = n;

96 96.     radius = r;

97 97.     moons = m;

98 98.     image = new ImageIcon(name + ".gif");

99 99. }

100 100.

101 101. public String toString()

102 102. {

103 103.     return name;

104 104. }

105 105.

106 106. /**

107 107.     Gets a description of the planet.

108 108.     @return the description

109 109. */

110 110. public String getDescription()

111 111. {

112 112.     return "Radius: " + radius + "\nMoons: " + moons + "\n";

113 113. }

114 114.

115 115. /**

116 116.     Gets an image of the planet.
117 117.          @return the image

118 118. */

119 119. public ImageIcon getImage()

120 120. {

121 121.          return image;

122 122. }

123 123.

124 124. private String name;

125 125. private double radius;

126 126. private int moons;

127 127. private ImageIcon image;

128 128. }

    <ul>
       <li>
    <tt>JSplitPane()</tt></li>
       <li>




1 <ul>

2       <li>

3 <tt>JSplitPane()</tt></li>

4       <li>

5 <tt>JSplitPane(int direction)</tt></li>

6       <li>

7 <tt>JSplitPane(int direction, boolean continuousLayout)</tt></li>

8       <li>

9 <tt>JSplitPane(int direction, Component first, Component second)</tt></li>

10      <li>

11 <tt>JSplitPane(int direction, boolean continuousLayout,</tt></li>

12      <li>
13 <tt> Component first, Component second)</tt>

14 construct a new split pane.</li>

15   <li>

16 <tt>boolean isOneTouchExpandable()</tt></li>

17   <li>

18 <tt>void setOneTouchExpandable(boolean b)</tt>

19 get and set the "one-touch expandable" property. When this property is set,</li>

20   <li>

21 the splitter has two icons to completely expand one or the other component.</li>

22   <li>

23 <tt>boolean isContinuousLayout()</tt></li>

24   <li>

25 <tt>void setContinuousLayout(boolean b)</tt>

26 get and set the "continuous layout" property. When this property is set,</li>

27   <li>

28 then the components are continuously updated when the splitter is moved.</li>

29   <li>

30 <tt>void setLeftComponent(Component c)</tt></li>

31   <li>

32 <tt>void setTopComponent(Component c)</tt>

33 These operations have the same effect, to set <tt>c</tt> as the first component</li>

34   <li>

35 in the split pane.</li>

36   <li>

37 <tt>void setRightComponent(Component c)</tt></li>

38   <li>

39 <tt>void setBottomComponent(Component c)</tt>
40 These operations have the same effect, to set <tt>c</tt> as the second</li>

41       <li>

42 component in the split pane.</li>

43 </ul>

44

45

46

47

48



                                AWT

           The Rendering Pipeline:-
One of the strengths of the 2D API is that shapes, text, and images are manipulated in many
of the same ways. In this section, we'll describe what happens to shapes, text, and images
after you give them to a Graphics2D object. Rendering is the process of taking some
collection of shapes, text, and images and figuring out how to represent them by coloring
pixels on a screen or printer. Graphics2D supports four rendering operations:

          Draw a shape's outline with the draw( ) method.
          Fill a shape's interior with the fill( ) method.
          Draw some text with the drawString( ) method.
          Draw an image with any of the many forms of the drawImage( ) method.

The graphics context represented by a Graphics2D object holds the following properties,
whose values are controlled by corresponding accessor methods (e.g., getFont( ) and
setFont( )):




paint

           The current paint (an object of type java.awt.Paint) determines what color or
           pattern will be used to fill a shape. This affects the drawing of shape outlines and text,
           as well. You can change the current paint using Graphics2D's setPaint( ) method.
           Note that the Color class implements the Paint interface, so you can pass Colors to
           setPaint( ) if you want to use solid colors.
stroke

         Graphics2D    uses the stroke to determine how to draw the outline of shapes that are
         passed to its draw( ) method. In graphics terminology, to "stroke" a shape means to
         take a path defined by the shape and effectively trace it with a pen or brush of a
         certain size and characteristics. For example, drawing the shape of a circle using a
         stroke that acts like a solid line would yield a washer or ring shape. The stroke
         object in the Graphics2D API is a little more abstract than that. In actuality it accepts
         the input shape to be stroked and returns an enclosed shape representing the outline,
         which Graphics2D then fills. You can set the current stroke using setStroke( ).
         The 2D API comes with a handy class, java.awt.BasicStroke, that implements
         different line widths, end styles, join styles, and dashing.



font

         Text is rendered by creating a shape that represents the characters to be drawn. The
         current font determines what shapes are created for a given set of characters. The
         resulting text shape is then filled. The current font is set using setFont( ). The 2D
         API gives applications access to all the TrueType and PostScript Type 1 fonts that are
         installed.



transformation

         Shapes, text, and images can be geometrically transformed before they are rendered.
         This means that they may be moved, rotated, and stretched. Graphics2D's
         transformation converts coordinates from "user space" to "device space." By default,
         Graphics2D uses a transformation that maps 72 units in user space to one inch on the
         output device. If you draw a line from point 0, 0 to point 72, 0 using the default
         transformation, it will be one inch long, regardless of whether it is drawn on your
         monitor or your printer. The current transformation can be modified using the
         translate( ), rotate( ), scale( ), and shear( ) methods.




compositing rule

         A compositing rule determines how the colors of a new drawing operation are
         combined with existing colors on the Graphics2D's drawing surface. This attribute is
         set using setComposite( ), which accepts an instance of
         java.awt.AlphaComposite. Compositing allows you to make parts of a drawing or
         image completely or partially transparent, or to combine them in other interesting
         ways.
clipping shape

       All rendering operations are limited to the interior of the clipping shape. No pixels
       outside this shape are modified. By default, the clipping shape allows rendering on the
       entire drawing surface (usually, the rectangular area of a Component). However, you
       can further limit this using any simple or complex shape (for example, text shapes).



rendering hints

       There are different techniques that can be used to render graphics primitives. Usually
       these represent a tradeoff between rendering speed and visual quality or vice versa.
       Rendering hints (constants defined in the RenderingHints class) specify which
       techniques to use.

Graphics primitives (shapes, text, and images) pass through the rendering engine in a series
of operations called the rendering pipeline. Let's walk through the pipeline. It can be reduced
to four steps; the first step depends on the rendering operation:

   1. Transform the shape. For shapes that will be filled, the shape is simply transformed
      using the Graphics2D's current transformation. For shapes whose outlines are drawn
      using draw( ), the current stroke is used to stroke the shape's outline. Then the
      stroked outline is transformed like any other filled shape. Text is displayed by
      mapping characters to shapes using the current font. The resulting text shapes are
      transformed like any other filled shape. Images are also transformed using the current
      transformation.
   2. Determine the colors to be used. For a filled shape, the current paint object determines
      what colors should be used to fill the shape. For drawing an image, the colors are
      taken from the image itself.
   3. Combine the colors with the existing drawing surface using the current compositing
      rule.
   4. Clip the results using the current clipping shape.

The rendering hints are used throughout to control the rendering quality.

       SHAPES:-

Drawing Shapes
With the AWT, you generally drew a shape by calling the drawXxx or fillXxx method of the
Graphics object. In Java 2D, you generally create a Shape object, then call either the draw or
fill method of the Graphics2D object, supplying the Shape object as an argument. For
example:

public void paintComponent(Graphics g) {
 super.paintComponent(g);
 Graphics2D g2d = (Graphics2D)g;
 // Assume x, y, and diameter are instance variables.
 Ellipse2D.Double circle =
     new Ellipse2D.double(x, y, diameter, diameter);
    g2d.fill(circle);
    ...
}

Most of the Shape classes define both a Shape.Double and a Shape.Float version of the
class. Depending on the version of the class, the coordinate locations are stored as either
double precision numbers (Shape.Double) or single precision numbers (Shape.Float). The
idea is that single precision coordinates might be slightly faster to manipulate on some
platforms. You can still call the familiar drawXxx methods of the Graphics class if you like;
the Graphics2D object inherits from the Graphics object. This approach is necessary for
drawString and drawImage and possibly is convenient for draw3DRect.

Shape Classes

Arguments to the Graphics2D draw and fill methods must implement the Shape interface.
You can create your own shapes, of course, but you can also use major built-in classes:
Arc2D, Area, CubicCurve2D, Ellipse2D, Gener_alPath, Line2D, QuadCurve2D,
Rectangle2D, and RoundRectangle2D. Each of these classes is contained in the
java.awt.geom package. Each of these classes, except for Area, Polygon, and Rectangle,
has float and dou_ble constructors.

The classes Polygon and Rectangle, holdovers from Java 1.1, also implement the Shape
interface. These two shapes are covered in Section 9.11 (Graphics Operations).

The most common constructors for these Shapes follow.

public Arc2D.Float(float left, float top, float width, float height,
                           float startAngle, float deltaAngle,
                           int closure)
public Arc2D.Double(double left, double top, double width, double height,
                    double startAngle, double deltaAngle,
                    int closure)

These constructors create an arc by selecting a portion of a full ellipse whose bounding
rectangle has an upper-left corner located at the (left, top). The vertex of the arc (ellipse) is
located at the origin of the bounding rectangle. The reference for the start angle is the positive
x-axis. Angles are specified in degrees and represent arc degrees, not true degrees. Arc
angles are defined such that the 45 degree line runs from the ellipse center to the upper-right
corner of the bounding rectangle. The arc closure is one of Arc2D.CHORD, Arc2D.OPEN, or
Arc2D.PIE.

public Area(Shape shape)

This constructor creates an Area with the given Shape. Areas support geometrical operations,
for example: add, subtract, intersect, and e_xclusiveOr.

public CubicCurve2D.Float(float xStart, float yStart,
                               float pX, float pY,
                               float qX, float qY, \
                               float xEnd, float yEnd)
public CubicCurve2D.Double(double xStart, double yStart,
                                 double pX, double pY,
                                 double qX, double qY,
                                 double xEnd, double yEnd)

These constructors create a CubicCurve2D shape representing a curve (spline) from (xStart,
yStart) to (xEnd, yEnd). The curve has two control points (pX, pY) and (qX, qY) that impact
the curvature of the line segment joining the two end points.

public Ellipse2D.Float (float left, float top, float width,
                             float height)
public Ellipse2D.Double(double left, double top,
                        double width,
                           double height)

These constructors create an ellipse bounded by a rectangle of dimen_sion width by height.
The Ellipse2D class inherits from the RectangularShape class and contains the same
methods as common to Rectangle2D and RoundRectangle2D.

public GeneralPath()

A GeneralPath is an interesting class because you can define all the line segments to create a
brand-new Shape. This class supports a handful of methods to add lines and Bézier (cubic)
curves to the path: closePath, curveTo, lineTo, moveTo, and quadTo. Appending a path
segment to a GeneralPath without first performing an initial moveTo generates an
IllegalPathStateException. An example of creating a GeneralPath follows:

GeneralPath path = new GeneralPath();
path.moveTo(100,100);
path.lineTo(300,205);
path.quadTo(205,250,340,300);
path.lineTo(340,350);
path.closePath();
public Line2D.Float(float xStart, float yStart, float xEnd,
                                                        float yEnd)
public Line2D.Double(double xStart, double yStart,
                      double xEnd, double yEnd)

These constructors create a Line2D shape representing a line segment from (xStart, yStart)
to (xEnd, yEnd).

public Line2D.Float(Point p1, Point p2) public Line2D.Double(Point p1,
Point p2)

These constructors create a Line2D shape representing a line segment from Point p1 to
Point p2.

public QuadCurve2D.Float(float xStart, float yStart,
                              float pX, double pY,
                              float xEnd, float yEnd)
public QuadCurve2D.Double(double xStart, double yStart,
                          double pX, double pY,
                             double xEnd, double yEnd)
These constructors create a Shape representing a curve from (xStart, yStart) to (xEnd,
yEnd). The point (pX, pY) represents a control point impacting the curvature of the line
segment connecting the two end points.

public Rectangle2D.Float(float top, float left, float width,
                              float height)
public Rectangle2D.Double(double top, double left,
                          double width, double height)

These constructors create a Rectangle2D shape with the upper-left corner located at (top,
left) and a dimension of width by height.

public RoundRectangle2D.Float(float top, float left,
                                   float width, float height,
                                   float arcX, float arcY)
public RoundRectangle2D.Double(double top, double left,
                               double width, double height,
                               double arcX, double arcY)

These two constructors create a RectangleShape with rounded corners. The upper-left
corner of the rectangle is located at (top, left), and the dimension of the rectangle is width
by height. The arguments arcX and arcY represent the distance from the rectangle corners
(in the respective x direction and y direction) at which the rounded curve of the corners start.

An example of drawing a circle (Ellispse2D with equal width and height) and a rectangle
(Rectangle2D) is presented in Listing 10.3. Here, the circle is filled completely, and an
outline of the rectangle is drawn, both based on the default context settings of the
Graphics2D object. Figure 10–1 shows the result. The method getCircle plays a role in
other examples throughout this chapter. ShapeExample uses WindowUtilities in Listing
14.1 and ExitListener in Listing 14.2 to create a closable JFrame container for the drawing
panel.

Most of the code examples throughout this chapter are presented as Java applications. To
convert the examples to applets, follow the given template:

import java.awt.*;
import javax.swing.*;
public class YourApplet extends JApplet {
  public void init() {
    JPanel panel = new ChapterExample();
    panel.setBackground(Color.white);
    getContentPane().add(panel);
  }
}

The basic idea is to create a JApplet and add the chapter example, which is implemented as
a JPanel, to the contentPane of the JApplet. Depending on the particular example you are
converting, you may need to set the background color of the JPanel. Once the corresponding
HTML file is created (with an applet of the same dimensions as the original JFrame), you can
either use appletviewer or convert the HTML file to support the Java Plug-In. See Section 9.9
(The Java Plug-In) for details on converting the HTML file.
Listing 10.3 ShapeExample.java
import javax.swing.*; // For JPanel, etc.
import java.awt.*;   // For Graphics, etc.
import java.awt.geom.*; // For Ellipse2D, etc.

/** An example of drawing/filling shapes with Java 2D in
 * Java 1.2 and later.
 */

public class ShapeExample extends JPanel {
 private Ellipse2D.Double circle =
  new Ellipse2D.Double(10, 10, 350, 350);
 private Rectangle2D.Double square =
  new Rectangle2D.Double(10, 10, 350, 350);

 public void paintComponent(Graphics g) {
   clear(g);
   Graphics2D g2d = (Graphics2D)g;
   g2d.fill(circle);
   g2d.draw(square);
 }
 // super.paintComponent clears off screen pixmap,
 // since we're using double buffering by default.
 protected void clear(Graphics g) {
   super.paintComponent(g);
 }

 protected Ellipse2D.Double getCircle() {
   return(circle);
 }

public static void main(String[] args) {
    WindowUtilities.openInJFrame(new ShapeExample(), 380, 400);
  }
}




       Areas:-

TextArea Frame in Java

Introduction

In this section, you will learn how to create TextArea on the frame. This program uses the
TextArea class of java.awt package. Here, we are going to create TextArea object. TextArea
object is a multiline region. It displays text only. You can read and edit the text only.

Description of this program:

This java program displays the text area using java AWT package. First of all, We have to
define class named "TextAreaFrame" under the java awt package. Inside this class we are
going to create TextArea field by using "TextArea("Welcome Roseindia",10,20)"
constructor.

TextArea("Welcome Roseindia",10,20): This constructs a new text area with "Welcome
Roseindia" string as text. Both vertical and horizontal scrollbars will be visible for this text
area according to the size specified in the above constructor i.e.10 for horizontal and 20 for
vertical.

Here is the code of this Program:

import java.awt.*;
import java.awt.event.*;

public class TextAreaFrame{
  public static void main(String[] args) {
  Frame frame=new Frame("Text Frame");
  TextArea textArea=new TextArea("Welcome Roseindia",10,20);
  frame.add(textArea);
  frame.setLayout(new FlowLayout());
  frame.setSize(250,250);
  frame.setVisible(true);
  frame.addWindowListener(new WindowAdapter(){
  public void windowClosing(WindowEvent e){
  System.exit(0);
  }
  });
  }
}



Output this program:
         STROKES:-
Introduction

This is a simple java program . In this section, you will learn how to create Line Drawing.
This program implements a line Drawing component. A java program explains the stroke
line i.e. how to make thick and thin line. For this we have used BasicStroke class. This
object is passed to the setStroke() method.

Program Description:

First of all, define a class named, LineDraw in program for creating a java AWT Line
Drawing component. This program uses the setStroke() method. The stroke describes the pen
and brush. It is used for drawing the line. This controls all drawing line attribute. It is a
suitable of all line drawing needs.

BasicStroke(): This is a constructor component. A BasicStroke object is used for several
different-different line drawing attributes. The BasicStroke() objects are immutable, So its
can be safely cached and shared.

Here is the code of this Program:

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

public class LineDraw extends Frame{
  Line2D line1 = new Line2D.Double(0, 0, 200, 200);
  Line2D line2 = new Line2D.Double(70, 80, 100, 200);
  Line2D line3 = new Line2D.Double(100, 150, 150,150);
  Stroke drawingStroke = new BasicStroke(2);
 public void paint(Graphics g) {
  Graphics2D graph = (Graphics2D)g;
  graph.setStroke(drawingStroke);
  graph.setPaint(Color.green);
  graph.draw(line1);
  graph.setPaint(Color.red);
  graph.draw(line2);
  graph.setPaint(Color.yellow);
  graph.draw(line3);

     }

     public static void main(String args[]) {
     Frame frame = new LineDraw();
     frame.addWindowListener(new WindowAdapter(){
     public void windowClosing(WindowEvent we){
     System.exit(0);
 }
     });
     frame.setSize(300, 250);
        frame.setVisible(true);
    }
}



Output of this program:




Download this program.

           PAINT:-
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class imageLoad extends Canvas {
Image img;
public imageLoad(Image img) {
this.img = img;
}
public void paint (Graphics g) {
if (img != null)
{
g.drawImage(img, 0, 0, 1000, 1000, this);
}
}
public void setImage (Image img){
this.img = img;
}
}
public class ImagesLoading implements ActionListener{
JFrame fr = new JFrame ("Image loading program Using awt");
Label Label1 = new Label("Label1 ");
Button Button1 = new Button("Click Here");
Image Image1;
imageLoad Canvas1;
FileDialog fd = new FileDialog(fr,"Open", FileDialog.LOAD);

void initialize (){
fr.setSize(500,500);
fr.setLocation(300,300);
fr.setBackground(Color.lightGray);
fr.setLayout(new FlowLayout());
fr.add(Label1);
fr.add(Button1);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Button1.addActionListener(this);
Canvas1 = new imageLoad(null);
Canvas1.setSize(1000,1000);
fr.add(Canvas1);
fr.show();
}
void imageload () {
fd.show();
if(fd.getFile() == null){
Label1.setText("You have not chosen any image files yet");
}
else{
String d = (fd.getDirectory() + fd.getFile());
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image1 = toolkit.getImage(d);
Canvas1.setImage(Image1);
Canvas1.repaint();
}
}

public void windowClosing(WindowEvent e){
System.exit(0);
}
public void windowActivated(WindowEvent e){
}
public void windowClosed(WindowEvent e){
}
public void windowDeactivated(WindowEvent e){
}
public void windowDeiconified(WindowEvent e){
}
public void windowIconified(WindowEvent e){
}
public void windowOpened(WindowEvent e){
}
public void actionPerformed(ActionEvent event){
Button b = (Button)event.getSource();
if(b == Button1){
imageload();
}
}
public static void main(String args[]){
ImagesLoading a = new ImagesLoading();
a.initialize();
}
}




Coordinate Transformations
Java 2D allows you to easily translate, rotate, scale, or shear the coordinate system. This
capability is very convenient: moving the coordinate system is often much easier than
calculating new coordinates for each of your points. Besides, for some data structures like
ellipses and strings, the only way to create a rotated or stretched version is through a
transformation. The meanings of translate, rotate, and scale are clear: to move, to spin, or to
stretch/shrink evenly in the x and/or y direction. Shear means to stretch unevenly: an x shear
moves points to the right, based on how far they are from the y-axis; a y shear moves points
down, based on how far they are from the x-axis.

The easiest way to picture what is happening in a transformation is to imagine that the person
doing the drawing has a picture frame that he lays down on top of a sheet of paper. The
drawer always sits at the bottom of the frame. To apply a translation, you move the frame
(also moving the drawer) and do the drawing in the new location. You then move the frame
back to its original location, and what you now see is the final result. Similarly, for a rotation,
you spin the frame (and the drawer), draw, then spin back to see the result. Similarly for
scaling and shears: modify the frame without touching the underlying sheet of paper, draw,
then reverse the process to see the final result.

An outside observer watching this process would see the frame move in the direction
specified by the transformation but see the sheet of paper stay fixed. On the other hand, to the
person doing the drawing, it would appear that the sheet of paper moved in the opposite way
from that specified in the transformation but that he didn't move at all.

You can also perform complex transformations by directly manipulating the underlying
arrays that control the transformations. This type of manipulation is a bit more complicated to
envision than the basic translation, rotation, scaling, and shear transformations. The idea is
that a new point (x2, y2) can be derived from an original point (x1, y1) as follows:
Note that you can only supply six of the nine values in the transformation array (the mxx
values). The coefficients m02 and m12 provide x and y translation of the coordinate system.
The other four transformation coefficients (m00, m01, m10, m11) provide rotation of the system.
For the transformation to preserve orthogonality ("straightness" and "parallelness" of lines),
the Jacobian (determinant) of the transformation matrix must equal 1. The bottom row is
fixed at [ 0 0 1 ] to guarantee that the transformations does not rotate the shape out of the x-y
plane (produce components along the z-axis). There are several ways to supply this array to
the AffineTransform constructor; see the AffineTransform API for details.

You use transformations in two basic ways—by creating an AffineTransform object or by
calling basic transformation methods. In the first approach, you can create an
AffineTransform object, set the parameters for the object, assign the AffineTransform to
the Graphics2D object through setTransform, and then draw a Shape. In addition, you can
use the AffineTransform object on a Shape to create a newly transformed Shape object.
Simply call the AffineTransform method, createTransformedShape, to create a new
transformed Shape. For complex transformations, creating an AffineTransform object is an
excellent approach because you can explicitly define the transformation matrix.

Core Note

You can apply a transformation to a Shape before drawing it. The AffineTransform method
createTransformedShape creates a new Shape that has undergone the transformation
defined by the AffineTransform object.

In the second approach, you can call translate, rotate, scale, and shear directly on the
Graphics2D object to perform basic transformations. The transformations applied to
Graphics2D object are cumulative; each transform method is applied to the already
transformed Graphics2D context. For example, calling rotate(Math.PI/2) followed by
another call to rotate(Math.PI/2) is equivalent to rotate(Math.PI). If you need to return
to a previously existing transformation state, save the Graphics2D context by calling
getTransform beforehand, perform your transformation operations, and then return to the
original Graphics2D context by calling setTransform. For example,

// Save current graphics context.
AffineTransform transform = g2d.getTransform();
// Perform incremental transformations.
translate(...);
rotate(...);
...
// Return the graphics context to the original state.
g2d.setTransform(transform);

Listing 10.13 illustrates a beautiful example of continuously rotating the coordinate system
while periodically writing the word "Java." The result is shown in Figure 10–9.

Listing 10.13 RotationExample.java
import java.awt.*;

/** An example of translating and rotating the coordinate
 * system before each drawing.
 */
public class RotationExample extends StrokeThicknessExample {
 private Color[] colors = { Color.white, Color.black };

 public void paintComponent(Graphics g) {
   clear(g);
   Graphics2D g2d = (Graphics2D)g;
   drawGradientCircle(g2d);
   drawThickCircleOutline(g2d);
   // Move the origin to the center of the circle.
   g2d.translate(185.0, 185.0);
   for (int i=0; i<16; i++) {
     // Rotate the coordinate system around current
     // origin, which is at the center of the circle.
     g2d.rotate(Math.PI/8.0);
     g2d.setPaint(colors[i%2]);
     g2d.drawString("Java", 0, 0);
   }
 }

public static void main(String[] args) {
    WindowUtilities.openInJFrame(new RotationExample(), 380, 400);
  }
}

Figure 10–9 A example of translating and rotating the coordinate system before
drawing text.

Shear Transformations

In a shear transformation, the coordinate system is stretched parallel to one axis. If you
specify a nonzero x shear, then x values will be more and more shifted to the right the farther
they are from the y-axis. For example, an x shear of 0.1 means that the x value will be shifted
10% of the distance the point is moved from the y-axis. A y shear is similar: points are shifted
down in proportion to the distance they are from the x-axis. In addition, both the x- and y-axis
can be sheared at the same time.

Probably the best way to visualize shear is in an example. The results for Listing 10.14 are
shown in Figure 10–10. Here, the x shear is increased from a value of 0.0 for the first square
to a value of +0.8 for the fifth square. The y values remain unaltered.

Listing 10.14 ShearExample.java
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

/** An example of shear transformations on a rectangle. */

public class ShearExample extends JPanel {
 private static int gap=10, width=100;
 private Rectangle rect = new Rectangle(gap, gap, 100, 100);

 public void paintComponent(Graphics g) {
  super.paintComponent(g);
  Graphics2D g2d = (Graphics2D)g;
  for (int i=0; i<5; i++) {
   g2d.setPaint(Color.red);
   g2d.fill(rect);
            // Each new square gets 0.2 more x shear.
            g2d.shear(0.2, 0.0);
            g2d.translate(2*gap + width, 0);
        }
    }

    public static void main(String[] args) {
      String title =
       "Shear: x shear ranges from 0.0 for the leftmost" +
       "'square' to 0.8 for the rightmost one.";
      WindowUtilities.openInJFrame(new ShearExample(),
                     20*gap + 5*width,
                     5*gap + width,
                     title);
    }
}

Figure 10–10 A positive x shear increases the shift in the x coordinate axis as y
increases. Remember, the positive y-axis goes from the upper-left corner to the lower-
left corner.




Clipping
Clipping is restricting of drawing to a certain area. This is done for efficiency reasons and to
create various effects.

In the following example we will be clipping an image.

Clipping.java

package com.zetcode;

import          java.awt.Graphics;
import          java.awt.Graphics2D;
import          java.awt.Image;
import          java.awt.RenderingHints;
import          java.awt.event.ActionEvent;
import          java.awt.event.ActionListener;
import          java.awt.geom.Ellipse2D;

import          javax.swing.ImageIcon;
import          javax.swing.JFrame;
import          javax.swing.JPanel;
import          javax.swing.Timer;


public class Clipping extends JPanel implements ActionListener {


             private int pos_x = 8;
             private int pos_y = 8;
             private int radius = 90;

             Timer timer;
             Image image;
    private double delta[] = { 3, 3 };

    public Clipping() {

        image = new ImageIcon("bardejov.png").getImage();

        timer = new Timer(15, this);
        timer.start();
    }

    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D) g;

        RenderingHints rh = new
RenderingHints(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);


        rh.put(RenderingHints.KEY_RENDERING,
               RenderingHints.VALUE_RENDER_QUALITY);

        g2d.setClip(new Ellipse2D.Double(pos_x, pos_y, radius, radius));

        g2d.drawImage(image,   5, 5, null);
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("Clipping");
        frame.add(new Clipping());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {

        int w = getWidth();
        int h = getHeight();

        if (pos_x < 0) {
            delta[0] = Math.random() % 4 + 5;
        } else if (pos_x > w - radius) {
            delta[0] = -(Math.random() % 4 + 5);
        }

        if (pos_y < 0 ) {
            delta[1] = Math.random() % 4 + 5;
        } else if (pos_y > h - radius) {
            delta[1] = -(Math.random() % 4 + 5);
        }

        pos_x += delta[0];
        pos_y += delta[1];

        repaint();
    }
}

In this example, we will clip an image. A circle is moving on the screen and showing a part
of the underlying image. This is as if we looked through a hole.

    g2d.setClip(new Ellipse2D.Double(pos_x, pos_y, radius, radius));

This is the key part of the code. Here we restrict drawing to a specific shape. In our case it is
a circle.

    if (pos_x < 0) {
        delta[0] = Math.random() % 4 + 5;
    } else if (pos_x > w - radius) {
        delta[0] = -(Math.random() % 4 + 5);
    }

If the circle hits the left or the right side of the window, the direction of the circle movement
changes randomly. Same for the top and bottom sides.




Figure: Clipping


Clipping shapes
In the following example, we will be clipping two shapes. A rectangle and a circle.

ClippingShapes.java

package com.zetcode;

import    java.awt.Color;
import    java.awt.Graphics;
import    java.awt.Graphics2D;
import    java.awt.Rectangle;
import    java.awt.RenderingHints;
import   java.awt.event.ActionEvent;
import   java.awt.event.ActionListener;
import   java.awt.geom.AffineTransform;
import   java.awt.geom.Ellipse2D;
import   java.awt.geom.GeneralPath;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class ClippingShapes extends JPanel implements ActionListener {

    private Timer timer;

    private    double rotate = 1;
    private    int pos_x = 8;
    private    int pos_y = 8;
    private    int radius = 60;

    private double delta[] = { 1, 1 };


    public ClippingShapes() {
        timer = new Timer(10, this);
        timer.start();
    }


    public void paint(Graphics g) {

           super.paint(g);

           Graphics2D g2d = (Graphics2D)g;

           g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);

           g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
                                RenderingHints.VALUE_RENDER_QUALITY);


           int w = getWidth();
           int h = getHeight();

           Rectangle rect1 = new Rectangle(0, 0, 200, 80);

           AffineTransform tx = new AffineTransform();
           tx.rotate(Math.toRadians(rotate), w / 2, h / 2);
           tx.translate(w / 2 - 100, h / 2 - 40);

           Ellipse2D circle = new Ellipse2D.Double(pos_x, pos_y, radius,
radius);

           step();

           GeneralPath path = new GeneralPath();
           path.append(tx.createTransformedShape(rect1), false);

           g2d.setColor(new Color(110, 110, 110));
           g2d.clip(circle);
           g2d.clip(path);

           g2d.fill(circle);

           g2d.setClip(new Rectangle(0, 0, w, h));

           g2d.draw(circle);
           g2d.draw(path);

       }


       public void step() {
           int w = getWidth();
           int h = getHeight();

           if (pos_x < 0) {
               delta[0] = 1;
           } else if (pos_x > w - radius) {
               delta[0] = -1;
           }

           if (pos_y < 0) {
               delta[1] = 1;
           } else if (pos_y > h - radius) {
               delta[1] = -1;
           }

           pos_x += delta[0];
           pos_y += delta[1];
       }


       public static void main(String[] args) {
           JFrame frame = new JFrame("Clipping shapes");
           frame.add(new ClippingShapes());
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           frame.setSize(350, 300);
           frame.setLocationRelativeTo(null);
           frame.setVisible(true);
       }


       public void actionPerformed(ActionEvent e) {
           rotate += 1;
           repaint();
       }
}

In our example, we have a bouncing circle and a rotating rectangle. When these shapes
overlap, the resulting area is filled with color.

    Rectangle rect1 = new Rectangle(0, 0, 200, 80);

    AffineTransform tx = new AffineTransform();
    tx.rotate(Math.toRadians(rotate), w / 2, h / 2);
    tx.translate(w / 2 - 100, h / 2 - 40);

The rectangle is being rotated. It is always positioned in the middle of the panel.
 GeneralPath path = new GeneralPath();
 path.append(tx.createTransformedShape(rect1), false);

Here we get the shape of the rotated rectangle.

 g2d.clip(circle);
 g2d.clip(path);

 g2d.fill(circle)

Here we restrict drawing to these two shapes. If they overlap, the interior of the resulting
shape is filled with color.

 g2d.setClip(new Rectangle(0, 0, w, h));

We reset the clip areas, before we draw the shapes.




Figure: Clipping Shapes




In this part of the Java 2D tutorial, we have talked about clipping.




Transparency
In this part of the Java 2D , we will talk about transparency. We will provide some basic
definitions and several interesting transparency effects.
Transparency explained
Transparency is the quality of being able to see through a material. The easiest way to
understand transparency is to imagine a piece of glass or water. Technically, the rays of light
can go through the glass and this way we can see objects behind the glass.

In computer graphics, we can achieve transparency effects using alpha compositing. Alpha
compositing is the process of combining an image with a background to create the
appearance of partial transparency. The composition process uses an alpha channel. Alpha
channel is an 8-bit layer in a graphics file format that is used for expressing translucency
(transparency). The extra eight bits per pixel serves as a mask and represents 256 levels of
translucency.
(answers.com, wikipedia.org)

The AlphaComposite class is used to work with transparency in Java 2D. It implements the
basic alpha compositing rules for combining source and destination pixels to achieve
blending and transparency effects with graphics and images. To create an AlphaComposite,
you provide two values. The rule designator and the alpha value. The rule specifies how we
combine source and destination pixels. Most often it is AlphaComposite.SRC_OVER. The
alpha value can range from 0.0f (completely transparent) to 1.0f (completely opaque).

Transparent rectangles
The first example will draw ten rectangles with different levels of transparency.

TransparentRectangles.java

package com.zetcode;


import   java.awt.AlphaComposite;
import   java.awt.Color;
import   java.awt.Graphics;
import   java.awt.Graphics2D;
import   javax.swing.JFrame;
import   javax.swing.JPanel;


public class TransparentRectangles extends JPanel {


     public void paint(Graphics g) {
         super.paint(g);

          Graphics2D g2d = (Graphics2D)g;
          g2d.setColor(Color.BLUE);


          for (int i = 1; i <= 10; i++) {

g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                        i * 0.1f));
            g2d.fillRect(50 * i, 20, 40, 40);
        }
     }


     public static void main(String[] args) {

          JFrame frame = new JFrame("Transparent Rectangles");
          frame.add(new TransparentRectangles());
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setSize(590, 120);
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
     }
}

In our example we draw 10 blue rectangles with various levels of transparency applied.

 g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, i *
0.1f));

This is the key line of the example. We use the forementioned AlphaComposite.SRC_OVER
rule. The alpha value dynamically changes in the for loop.




Figure: Transparent rectangles


Fade out demo
In the next example, we will fade out an image. The image will gradually get more
transparent until it is completely invisible.

FadeOut.java

package com.zetcode;

import java.awt.AlphaComposite;
import java.awt.Graphics;

import java.awt.Graphics2D;
import java.awt.Image;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import   javax.swing.ImageIcon;
import   javax.swing.JFrame;
import   javax.swing.JPanel;
import   javax.swing.Timer;
public class FadeOut extends JPanel implements ActionListener {

       Image castle;
       Timer timer;
       private float alpha = 1f;

       public FadeOut() {
           castle = new ImageIcon("bardejov.jpg").getImage();
           timer = new Timer(20, this);
           timer.start();
       }

       public void paint(Graphics g) {
           super.paint(g);

           Graphics2D g2d = (Graphics2D) g;


g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                    alpha));
        g2d.drawImage(castle, 10, 10, null);

       }

       public static void main(String[] args) {

           JFrame frame = new JFrame("Fade out");
           frame.add(new FadeOut());
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           frame.setSize(280, 240);
           frame.setLocationRelativeTo(null);
           frame.setVisible(true);
       }


       public void actionPerformed(ActionEvent e) {
           alpha += -0.01f;
           if (alpha <= 0) {
               alpha = 0;
               timer.stop();
           }
           repaint();
       }
}

With the AlphaComposite we gradually fade out the image on the panel. The picture comes
from Bardejov, a little town in east part of Slovakia.

 g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
alpha));

Working with transparency.

    alpha += -0.01f;

In the actionPerformed() method we gradually decrease the alpha value. Note, that the alpha
value must not be negative.
Waiting
In this example, we use transparency effect to create a waiting demo. We will draw 8 lines
that will gradually fade out creating an illusion, that a line is moving. Such effects are often
used to inform users, that a lengthy task is going on behind the scenes. An example is
streaming video over the Internet.

Waiting.java

package com.zetcode;


import   java.awt.AlphaComposite;
import   java.awt.BasicStroke;
import   java.awt.Graphics;
import   java.awt.Graphics2D;
import   java.awt.RenderingHints;
import   java.awt.event.ActionEvent;
import   java.awt.event.ActionListener;
import   javax.swing.JFrame;
import   javax.swing.JPanel;
import   javax.swing.Timer;



public class Waiting extends JPanel implements ActionListener {

     Timer timer;
     int count;

     public Waiting() {

          timer = new Timer(80, this);
          timer.setInitialDelay(190);
          timer.start();
     }


     public void paint(Graphics g) {
         super.paint(g);

          Graphics2D g2d = (Graphics2D) g;
          g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                              RenderingHints.VALUE_ANTIALIAS_ON);
          g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
                              RenderingHints.VALUE_RENDER_QUALITY);

          final   double[][] trs = {
              {   0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1.0 },
              {   1.0, 0.0, 0.15, 0.30, 0.5, 0.65, 0.8, 0.9 },
              {   0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65, 0.8 },
              {   0.8, 0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65},
              {   0.65, 0.8, 0.9, 1.0, 0.0, 0.15, 0.3, 0.5 },
              {   0.5, 0.65, 0.8, 0.9, 1.0, 0.0, 0.15, 0.3 },
              {   0.3, 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, 0.15 },
              {   0.15, 0.3, 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, }
          };

          int width, height;
             width = getWidth();
             height = getHeight();

             g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND,
                                           BasicStroke.JOIN_ROUND));
             g2d.translate(width/2, height/2);

             for (int i = 0; i < 8; i++) {

g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,

(float)trs[count%8][i]));

                 g2d.rotate(Math.PI/4f);
                 g2d.drawLine(0, -10, 0, -40);
             }
      }

          public void actionPerformed(ActionEvent e) {
              repaint();
              count++;
          }

      public static void main(String[] args) {
          JFrame frame = new JFrame("Waiting");
          frame.add(new Waiting());
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setSize(300, 200);
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
      }
}

We draw eight lines with eight different alpha values.

final double[][] trs = { ... }

This is a two dimensional array of transparency values used in this demo. There are 8 rows,
each for one state. Each of the 8 lines will continuosly use these values.

 g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND));

We make the lines a bit thicker, so that they are better visible. We draw the lines with
rounded caps.

    g2d.rotate(Math.PI/4f);
    g2d.drawLine(0, -10, 0, -40);

This code will draw each of the eight lines.
Figure: Waiting


Composition
In this part of the Java 2D programming tutorial, we will define compositing operations.

Compositing is the combining of visual elements from separate sources into single images.
They are used to create the illusion that all those elements are parts of the same scene.
Compositing is widely used in film industry to create crowds, entire new worlds which would
be expensive or impossible to create otherwise. (wikipedia.org)

Operations
There are several compositing operations. We will show some of them in the next code
example. The AlphaComposite class implements basic alpha compositing rules for
combining source and destination colors to achieve blending and transparency effects with
graphics and images.

Say we want to draw two objects on a panel. The first object drawn is called a destination.
The second one a source. The AlphaComposite class determines how these two are going to
be blended together. If we have a AlphaComposite.SRC_OVER rule, the pixels of the source
object will be drawn, where the two objects overlap.

Compositing.java

package com.zetcode;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;
public class Compositing extends JPanel {

       int rules[] = {
           AlphaComposite.DST,
           AlphaComposite.DST_ATOP,
           AlphaComposite.DST_OUT,
           AlphaComposite.SRC,
           AlphaComposite.SRC_ATOP,
           AlphaComposite.SRC_OUT,
       };


       public void paint(Graphics g) {

           Graphics2D g2d = (Graphics2D) g;

           for (int x=20, y=20, i=0; i < rules.length; x+=60, i++) {

               AlphaComposite ac = AlphaComposite.getInstance(rules[i], 0.8f);

               BufferedImage buffImg = new BufferedImage(60, 60,
                                           BufferedImage.TYPE_INT_ARGB);
               Graphics2D gbi = buffImg.createGraphics();

               gbi.setPaint(Color.blue);
               gbi.fillRect(0, 0, 40, 40);
               gbi.setComposite(ac);

               gbi.setPaint(Color.green);
               gbi.fillRect(5, 5, 40, 40);

               g2d.drawImage(buffImg, x, y, null);
           }
       }

       public static void main(String[] args) {

           JFrame frame = new JFrame("Composition");
           frame.add(new Compositing());
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           frame.setSize(400, 120);
           frame.setLocationRelativeTo(null);
           frame.setVisible(true);
       }
}

We draw two rectangles and combine them with six different compositing operations.

    int rules[] = {
        AlphaComposite.DST,
        AlphaComposite.DST_ATOP,
        AlphaComposite.DST_OUT,
        AlphaComposite.SRC,
        AlphaComposite.SRC_ATOP,
        AlphaComposite.SRC_OUT,
    };

Here we have six different compositing rules. Only two of these have practical significance.
If not sure what compositing rule to use, pick up the SRC_OVER rule.
 AlphaComposite ac = AlphaComposite.getInstance(rules[i]);

Here we get the AlphaComposite class.

 BufferedImage buffImg = new BufferedImage(60, 60,
BufferedImage.TYPE_INT_ARGB);
 Graphics2D gbi = buffImg.createGraphics();

We use a buffer image to perform the composition operations.

 gbi.setComposite(ac);

Sets the Composite for the Graphics2D context.

 g2d.drawImage(buffImg, x, y, null);

We draw the image on the panel.




Figure: Composition


Sun and Cloud
In the next example we show the Sun coming from behind a cloud. We will use composition
technique in this animation.

SunAndCloud.java

package com.zetcode;

import   java.awt.AlphaComposite;
import   java.awt.Graphics;
import   java.awt.Graphics2D;
import   java.awt.Image;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import   javax.swing.ImageIcon;
import   javax.swing.JFrame;
import   javax.swing.JPanel;
import   javax.swing.Timer;


public class SunAndCloud extends JPanel implements ActionListener {
    Image sun;
    Image cloud;
    Timer timer;
    private float alpha;

    public SunAndCloud() {
        sun = new
ImageIcon(this.getClass().getResource("sun.png")).getImage();
        cloud = new
ImageIcon(this.getClass().getResource("cloud.png")).getImage();
        timer = new Timer(800, this);
        timer.start();
        alpha = 1f;
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;

         BufferedImage buffImg = new BufferedImage(220, 140,
                                     BufferedImage.TYPE_INT_ARGB);
         Graphics2D gbi = buffImg.createGraphics();

        AlphaComposite ac =
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);

         gbi.drawImage(sun, 40, 30, null);
         gbi.setComposite(ac);
         gbi.drawImage(cloud, 0, 0, null);

         g2d.drawImage(buffImg, 20, 20, null);
    }

    public static void main(String[] args) {

         JFrame frame = new JFrame("Sun & Cloud");
         frame.add(new SunAndCloud());
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setSize(300, 210);
         frame.setLocationRelativeTo(null);
         frame.setVisible(true);
    }


    public void actionPerformed(ActionEvent e) {
        alpha -= 0.1;
        if (alpha <= 0) {
            alpha = 0;
            timer.stop();
        }
        repaint();
    }
}

The Sun comes from behind the cloud. The cloud finally disappears.

 sun = new ImageIcon(this.getClass().getResource("sun.png")).getImage();
 cloud = new
ImageIcon(this.getClass().getResource("cloud.png")).getImage();
We have two images, the Sun and the cloud.

 AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
alpha);

We use the AlphaComposite.SRC_OVER rule. Here the source blends with destination and
overwrites empty pixels.




Figure: Sun & Cloud




In this part of the Java 2D tutorial, we have talked about image composition.



RENDERING HINTS IN AWT:-

This Java tutorial teaches you about adding the rendering hints to a graphics on the frame.
The rendering hints uses the Graphics2D and creates the following image.

Description of program:

This program uses the Graphics2D class for rendering hints and draw or construct the given
following image.

Description of code:

Graphics2D():
This is the constructor of Graphics2D class that extends the Graphics class to provide

KEY_ANTIALIASING:
This is an antialiasing hint key.

VALUE_ANTIALIAS_ON:
This is a antialiasing hints values and rendered with it.
setRenderingHint():
This method sets the values in Graphics2D object for rendering algorithm.

GradiantPaint(float x1, float y1, Color col1, float x2, float y2, Color col2):
This is the constructor of GradiantPaint class that provides a way for filling the shapes with
gradient color pattern. It creates the simple acyclic GradientPaint object. It takes the
following arguments:

  x1: This is the x coordinate of first specified point.
 y1: This is the y coordinate of first specified point.
 col1: This is the color of first specified point.
 x2: This is the x coordinate of second specified point.
 y2: This is the y coordinate of second specified point.
  col2: This is the color of second specified point.

Ellipse2D():
This is the constructor of an abstract class Ellipse2D that defines bounding rectangle and
constructs an ellipse.

transform():
This is the constructor of Transform Class. This is an abstract class that transform a source
tree into a tree result.

Here is the code of program:

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

public class RanderingHintsGraphics extends Frame{
  public static void main(String[] args) {
  new RanderingHintsGraphics();
  }
  public RanderingHintsGraphics(){
  setTitle("Add RenderingHints to a Graphics");
  setSize(300,200);
  setVisible(true);
  addWindowListener(new WindowAdapter(){
  public void windowClosing(WindowEvent we){
  System.exit(0);
  }
  });
  }
  public void paint(Graphics g){
  Graphics2D d = (Graphics2D)g;
  d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  GradientPaint gpaint = new GradientPaint(
  50, 80, Color.gray,50, 110, Color.lightGray);
  Ellipse2D el = new Ellipse2D.Double(5, 30, 280, 160);
  d.setPaint(gpaint);
    d.fill(el);
    double rotation = Math.PI/8;
    d.transform(AffineTransform.getRotateInstance(rotation));
    Font font = new Font("Serif", Font.TRUETYPE_FONT, 50);
    d.setFont(font);
    d.setPaint(Color.white);
    String str = "RoseIndia";
    d.drawString(str,80,60);
    }
}


Download this example.

Output of program:




READERS AND WRITERS FOR IMAGE:-

How to read image files

Here is a program to read an image:




Test.java
import   java.awt.*;
import   java.awt.image.*;
import   javax.swing.*;
import   java.awt.geom.*;

public class Test extends JFrame {
    BufferedImage bi;
    Graphics big; // stands for Buffered Image Graphics
    Toolkit toolkit;
    MediaTracker tracker;
    int width;
    int height;

     public Test() {
         toolkit = Toolkit.getDefaultToolkit();
         tracker = new MediaTracker(this);

          Image image = toolkit.getImage("mandel.gif");
          tracker.addImage(image, 0);
           try {
             // load all the image for later use
               tracker.waitForAll();
           } catch (InterruptedException ex) {
           }

           width = image.getWidth(this);
           height = image.getHeight(this);

           bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
           big = bi.getGraphics();
           big.drawImage(image, 0, 0, this);
     }

     public void paint(Graphics g) {
         setBackground(Color.white);

          Graphics2D g2 = (Graphics2D)g;

          TexturePaint paint = new TexturePaint(bi,
                              new Rectangle2D.Double(0,0,width,height));
          g2.setPaint(paint);
          g2.fill(new Ellipse2D.Double(25,50,255,125));

     }

     public static void main(String[] args) {
         JFrame f = new Test();
         f.setSize(300,200);
         f.setVisible(true);
         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     }
}
Here is a rewrite of the above program:
ReadTest1.java

import   java.awt.*;
import   java.awt.image.*;
import   javax.swing.*;
import   java.awt.geom.*;
import javax.imageio.*;
import java.io.*;

public class ReadTest1 extends JFrame {
    BufferedImage bi;
    int width;
    int height;

        public ReadTest1() {
            try {
                  bi = ImageIO.read(new File("mandel.gif"));
            } catch (IOException ex) {
                ex.printStackTrace();
                System.exit(0);
            }

              height = bi.getHeight();
              width = bi.getWidth();
        }

        public void paint(Graphics g) {
            setBackground(Color.white);

              Graphics2D g2 = (Graphics2D)g;

              TexturePaint paint = new TexturePaint(bi,
                                  new Rectangle2D.Double(0,0,width,height));
              g2.setPaint(paint);
              g2.fill(new Ellipse2D.Double(25,50,255,125));

        }

        public static void main(String[] args) {
            JFrame f = new ReadTest1();
            f.setSize(300,200);
            f.setVisible(true);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
}


           ImageIO class has the following read method
               o public static BufferedImage read(File input) throws IOException
               o public static BufferedImage read(InputStream input) throws IOException
               o public static BufferedImage read(URL input) throws IOException
               o public static BufferedImage read(ImageInputStream stream) throws IOException

Here is another example using a different read method
import       java.awt.*;
import       java.awt.image.*;
import       javax.swing.*;
import       java.awt.geom.*;
import       javax.imageio.*;
import       java.io.*;

public class ReadTest2 extends JFrame {
    BufferedImage bi;
    int width;
    int height;
    public ReadTest2() {
        try {
              InputStream in = new FileInputStream("mandel.gif");
              bi = ImageIO.read(in);
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(0);
        }

          height = bi.getHeight();
          width = bi.getWidth();
    }

    public void paint(Graphics g) {
        setBackground(Color.white);

          Graphics2D g2 = (Graphics2D)g;

          TexturePaint paint = new TexturePaint(bi,
                              new Rectangle2D.Double(0,0,width,height));
          g2.setPaint(paint);
          g2.fill(new Ellipse2D.Double(25,50,255,125));

    }

    public static void main(String[] args) {
        JFrame f = new ReadTest2();
        f.setTitle("ReadTest2");
        f.setSize(300,200);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}



How to write an image to files (or other output stream)

WriteTest1

import   java.awt.*;
import   java.awt.image.*;
import   java.awt.geom.*;
import   javax.imageio.*;
import   java.io.*;

public class WriteTest1 {
    public static void main(String[] args) {
        int width = 300;
        int height = 300;
        BufferedImage bi = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bi.createGraphics();
        g2.setColor(Color.white);
        g2.fillRect(0,0, width, height);
        g2.setStroke(new BasicStroke(10.0f));
        g2.setPaint(new GradientPaint(0,0, Color.green, 50,50,
Color.yellow, true));
              g2.fill(new Ellipse2D.Float(50,50,200,200));
              File f = new File("image.png");
              try {
                      // png is an image format (like gif or jpg)
                      ImageIO.write(bi, "png", f);
              } catch (IOException ex) {
                  ex.printStackTrace();
              }
        }
}


           png is an image format. It is similar to jpg or gif. You can replace "png" by "jpg". There is no
            gif writter provided in Sun's java. So be careful.
           Here are different write methods.
                o  static boolean write(RenderedImage im, String formatName, File
                   output) throws IOException
                o static boolean write(RenderedImage im, String formatName,
                   OutputStream output) throws IOException
                o static boolean write(RenderedImage im, String formatName,
                   ImageOutputStream output) throws IOException
           The image file is written to the file image.png. Here is the output file




Here is another way to write the same program:
WriteTest2.java
import       java.awt.*;
import       java.awt.image.*;
import       java.awt.geom.*;
import       javax.imageio.*;
import       java.io.*;

public class WriteTest2 {
    public static void main(String[] args) {
        int width = 300;
        int height = 300;
        BufferedImage bi = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bi.createGraphics();
        g2.setColor(Color.white);
        g2.fillRect(0,0, width, height);
        g2.setStroke(new BasicStroke(10.0f));
        g2.setPaint(new GradientPaint(0,0, Color.green, 50,50,
Color.yellow, true));
        g2.fill(new Ellipse2D.Float(50,50,200,200));

            try {
                    FileOutputStream out = new FileOutputStream("image.jpg");
                    ImageIO.write(bi, "jpg", out);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
     }
}


Supported format

Here is a program that shows you the list of formats supported for writing and reading.
GetList.java

import javax.imageio.*;

public class GetList {
    public static void main(String args[]) {
         String readerNames[] =
            ImageIO.getReaderFormatNames();
         printlist(readerNames, "Reader names:");
         String readerMimes[] =
             ImageIO.getReaderMIMETypes();
         printlist(readerMimes, "Reader MIME types:");
         String writerNames[] =
            ImageIO.getWriterFormatNames();
         printlist(writerNames, "Writer names:");
         String writerMimes[] =
             ImageIO.getWriterMIMETypes();
         printlist(writerMimes, "Writer MIME types:");
     }

         private static void printlist(String names[], String title) {
             System.out.println(title);
             for (int i=0, n=names.length; i<n; i++) {
                System.out.println("\t" + names[i]);
              }
           }
}
Output

Reader names:
        jpeg
        gif
        JPG
        png
        jpg
        JPEG
Reader MIME types:
        image/png
        image/jpeg
        image/x-png
        image/gif
Writer names:
        jpeg
        JPG
        png
        jpg
        PNG
        JPEG
Writer MIME types:
        image/png
        image/jpeg
        image/x-png


ImageReader


Bart.gif

import     java.awt.image.*;
import     javax.imageio.*;
import     java.io.*;
import     java.util.*;
import     javax.imageio.stream.*;

public class ImageReaderTest1 {
    public static void main(String[] args) {
        // get all the reader that can read the format gif
        Iterator readers = ImageIO.getImageReadersByFormatName("gif");
        // get the first one among these reader
        ImageReader reader = (ImageReader)readers.next();
        Object source; // File or InputStream

           // first source
           source = new File("Bart.gif");

           // create image input stream
           ImageInputStream iis = null;
           try {
               // source is a file or an input stream
               iis = ImageIO.createImageInputStream(source);
           } catch (IOException ex) {
               ex.printStackTrace();
               System.exit(0);
           }

           // attached to the reader by calling
           reader.setInput(iis, true);


           // example
           try {
               System.out.println(reader.getHeight(0));
           } catch (IOException ex) {
               ex.printStackTrace();
               System.exit(0);
           }
     }
}


        For further reference, refer to ImageReader

ImageWriter

The output file xxx.png




ImageWriterTest1.java

import    java.awt.*;
import    javax.swing.*;
import    java.awt.geom.*;
import    java.awt.image.*;
import    javax.imageio.*;
import    java.io.*;
import    java.util.*;
import    javax.imageio.stream.*;

public class ImageWriterTest1 {
    public static void main(String[] args) {
        // get all the writers that can write png format
        Iterator writers = ImageIO.getImageWritersByFormatName("png");
        // get the first one
        ImageWriter writer = (ImageWriter)writers.next();

       // Once an ImageWriter has been obtained, its destination must be
set to an ImageOutputStream:
        File f = new File("xxx.png");
        ImageOutputStream ios;
        try {
            ios = ImageIO.createImageOutputStream(f);
            writer.setOutput(ios);
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(0);
        }

         // Finally, the image may be written to the output stream:

      BufferedImage bi = new BufferedImage(200, 200,
BufferedImage.TYPE_INT_RGB);
      Graphics2D g2 = bi.createGraphics();
      g2.setPaint(new GradientPaint(0,0, Color.orange, 0,50, Color.blue ,
true));
        g2.fillRect(0,0, 200, 200);
        g2.setPaint(new GradientPaint(0,0, Color.cyan, 50,50, Color.red,
true));
        g2.fill(new Ellipse2D.Float(50,50,200,200));
        try {
            writer.write(bi);
        } catch (IOException ex) {
            ex.printStackTrace();
      }
    }
}




Image Manipulation,:-

If a picture is worth a thousand words, what words do you use when the picture is in the wrong
format? Not exactly a Zen koan, but a valid question whose answer is JIMI, the Java Image
Management Interface from Activated Intelligence.

JIMI is a toolkit for reading, writing, viewing and manipulating images in multiple-graphics file formats.
JIMI supports an impressive number of image formats, but if your target format is not supported,
JIMI's open design allows you to add your format while taking advantage of key JIMI features. As
you'd hope and expect, JIMI is platform-neutral 100% Pure Java that works with Java l.0.x and 1.1.x,
and with the current beta versions of Java 1.2.

This article will let you know if JIMI has the features that will lighten your load and tighten your code.
The "Overview" section examines JIMI's major features and identifies how JIMI can fit into your
project. The "Down to Business" section focuses on technical topics and code samples.

Overview
When you finish this overview, you'll understand JIMI's key features and be able to identify how JIMI
can provide a strategic advantage to your projects and products.

JIMI Encodes and Decodes Images
Life gets pretty frustrating when you run into communication barriers. The unruly universe of the
World Wide Web, with its varied platforms, browsers, languages and users, can make a programmer
cry out for simplicity. Java simplifies programming across varied platforms and environments. JIMI
delivers stunning simplicity to the Java programmer who needs to work with the following formats:
GIF
JPEG
Portable Network Graphics Format (PNG)
Adobe Photoshop (PSD)
Targa (TGA)
Windows Bitmap (BMP)
OS/2 Bitmap (BMP)
ICO and CUR
Macintosh PICT (PCT)
Tag Image File Format (TIFF)
X Bitmap (XBM)
X Pixmap (XPM)
Sun Rasterfile (RAS)
PCX

The following code snippet reads a Photoshop file and writes it back to disk as a PNG file. It couldn't
be easier!
Image image = Jimi.getImage("myImage.PSD");
Jimi.putImage(image, "myImage.PNG");

See Listing 1 for a complete and equally simple application version of this code.

Activated Intelligence's customers are using JIMI's simple encode/decode features to add serious
power to their applications. Put JIMI in your applets and applications to easily browse and view most
of the images that come your way. Place JIMI in your File Upload Servlet and rest assured that it'll
accept a wide range of image files for conversion to popular viewing formats. Expect the number of
supported formats to grow with each release.

Image Manipulation with JIMI
You should now be confident that you can read, write and view most image formats. JIMI helps you
manipulate these images simply and uniformly. Going far beyond the AWT, JIMI gives you power over
your images with pixel-level access. With this feature you can write new and standard image
manipulation routines. Activated packed JIMI with a few favorites, such as:
Scaling (does thumbnails)
Cropping
Color-reduction
Smoothing
Flipping
Edge detection
Embossing
Tiling
Oil painting
Blur
Gamma adjustment
Smoothing

If you choose to write a custom routine using the JIMI pixel access interface, it'll work on all the
supported formats.

What Makes JIMI Special?
If reading, writing, viewing and manipulating multiple image formats across multiple platforms isn't
enough for you, JIMI has more. It's the foundation for imaging within the Java environment. What
makes Activated so confident in JIMI? JIMI knows Java! JIMI protects the Java programmer from
some vexing conditions in the Java environment. JIMI is ready to work with the Java community and
harness its power. Following are four of JIMI's special attributes:

    1. Big images, little JVM: How much memory will your Java application have at runtime? You
       may not know. JIMI has a fast, powerful and unique virtual memory management (VMM)
       system that lets you do more in your little JVM than you ever imagined. Using JIMI, a
       developer can load a 10000x10000 image in a JVM that is allocated only the standard 16 mb
       of heap space. JIMI uses memory only for the parts in use at that moment. How? JIMI
       leverages its fine-grained control over image access to implement a highly efficient virtual
       memory system tailored to the needs of large images. But the developer doesn't need to
       know the details to use the VMM. JIMI simply has the information you need buffered for fast
       access.
    2. Can I use JIMI on the server? Yes. JIMI can work independently of the AWT. Use JIMI in
       servlets, Enterprise Java-Beans or any other AWT-less server-based environment. When you
       have lots of image translation or manipulation to do, JIMI lets you move the processing from
       the client to the server.
    3. JIMI is extensible! Adding a new image format? No problem. JIMI's capabilities are
       dynamically extensible, allowing you to add new image formats. Each new format can
       seamlessly take advantage of all JIMI's core features.
       Because we designed JIMI to be easily and openly extended, Activated Intelligence is on the
       lookout for new image manipulation routines and image encoders/decoders. Developers can
       contact Activated Intelligence at www.activated.com to make arrangements for review and
       possible equitable use of their JIMI-based code.
    4. Flexible footprint: With Activated Intelligence and independent developers adding new
       features and formats to the JIMI system, JIMI is growing! But what if you want to use it where
       memory is a constraint or the code needs to be moved over a slow network? JIMI is a
       modular system that allows the formats and features to "Plug and Play."

Down to Business: Programming with JIMI
Now that you know what JIMI can do for you, the rest of this article will show you how to become a
JIMI developer. When you finish reading, you should know how to program with JIMI.

JIMI is made up of several tightly integrated components that provide a powerful set of features in a
modular and extensible architecture. Figure 1 illustrates JIMI's internals.




                                                 Figure 1:

The JIMI core provides the central functionality to support all other components. These classes
handle the transparent AWT Image import/export, seamless VMM and other advanced imaging
features. With a high-level understanding of the JIMI core, the developer can concentrate on the
project.

The JIMI Image Read/Write Interface
The most fundamental use for JIMI is loading and saving images. JIMI's Image Read/Write Interface
includes an intuitive front end with familiar and easy-to-use methods for image load-and-save
operations. See how the "Jimi" class provides intuitive one-call methods for loading and saving
images:

public static Image getImage(String filename);

public static Image putImage(Image image, String filename)
throws JimiException

Developers that have loaded images using the core Java API will be familiar with the getImage
method. Jimi.getImage also provides asynchronous image loading, but with JIMI's added full range of
format support, on-demand VMM and animated image support. Other convenient variations of
getImage are provided, including a similar getImageProducer method used to apply filters or for use in
an AWT-less environment. With these variations there's always a single method you can use to load
an image to suit your needs.

Not surprisingly, the putImage methods are equally easy. Give JIMI the image (or ImageProducer),
tell it where to save it and JIMI does the rest. Again, putImage has all the common variations to
ensure that saving your image with JIMI is a one-call operation. Images saved will also automatically
inherit any properties they were loaded with, such as compression scheme and interlacing options,
even if you're saving to a different format.
With these methods in your toolbox you have everything you need to quickly add basic load/save
support for a diverse range of formats to your programs. JIMI takes things a step further by also
enabling you to dissect and reassemble image files containing several frames of image data, such as
animated GIFs. This is achieved with two new interfaces: JimiReader and JimiWriter. For more on
working with multi-image files, see Listing 2.

See how easily JIMI's features enhance your programs? To get the JIMI advantage, just change the
one getImage line in your code. Add one call to JIMI's "putImage" and the job is done.

The Image Manipulation Interface
Now you can easily load and save images, but how about modifying them? For this, JIMI has full
compatibility with the AWT's ImageFilter model of image manipulation as well as compatibility with
new JDK features like Java 2D. A common image-processing operation is applying an ImageFilter.

With JIMI you can easily load an image, apply a filter and then save the image again. This code will
crop a 100x100 region of an image and then save it:

ImageProducer p1=Jimi.getImageProducer("i.gif");
ImageFilter f=new CropImageFilter(0,0,100,100);
ImageProducer p2=new FilteredImageSource(f, p1);
Jimi.putImage(p2, "i.gif");

JIMI also provides more sophisticated image manipulation tools. Without JIMI, a developer who wants
to access specific pieces of image data needs to use a PixelGrabber to get an image into an array of
pixel data and then create a MemoryImageSource to build the modified image. This is expensive in
both time and memory. JIMI provides random access to pixel data in its images. You have the power
associated with an in-memory buffer and the flexibility that comes with all of JIMI's interfaces. Access
your image in comfortable chunks and still benefit from JIMI's VMM capabilities.

Two additional key interfaces are JimiRasterImage and JimiBufferedRasterImage. The former
provides a uniform interface to images created by JIMI regardless of their ColorModel type and form
of primitive storage, letting you access their pixel data as RGB color values. The methods for this
access are:


public void getRectangleRGB(int x, int y,
int w, int h, int[] buffer,
int offset, int scansize)

public void getRowRGB(int y, int[] buffer,
int offset)

public int getPixelRGB(int x, int y)

JimiBufferedRasterImage extends this set of methods to include symmetrical "setters" for changing
pixel data. The Jimi class provides a one-call method for accessing these objects. Just replace
"getImage" with "getRasterImage." JIMI also provides buffered access to these images with
"getBufferedRasterImage" and the JimiBufferedRasterImage object. For more detail see Listing 3.

The Encoder/Decoder Interface
Now you can load, view, save and manipulate images for all JIMI's image formats, but what if your pet
format isn't supported? Using JIMI's extension API you can add a new format module, leveraging all
of JIMI's features and much of the work done for you. Implementing an encoder or decoder with JIMI
gives you free image production, VMM support and seamless integration with the rest of JIMI.

Although greatly simplified, implementing format modules still deserves a more thorough guide than
can be given in this article. Interested developers should take a look at
www.activated.com/jimi/addformat/ for a step-by-step guide.
Conclusion
Now you know: JIMI's simple elegance lets you read, write, view and manipulate most images across
multiple platforms in varied Java environments. You know when and where JIMI can help bring your
product to release faster and with more features. You also know enough to get started writing
powerful and effective imaging code using the JIMI toolkit. So go ahead, visit us at
www.activated.com, download JIMI and "get the picture."

About the Authors
Luke Gorrie is a Java programmer and the lead developer of JIMI at Activated Intelligence. He can be
reached at luke@activated.com

Michael Sick is a Java programmer, a Java advocate and the director of strategic development for
Activated Intelligence. Contact him at mike@activated.com




Listing 1.

Basic image conversion with JIMI

import com.activated.jimi.*;
import java.awt.Image;

public class JimiIsReallyEasy {
 public static void main(String[] args)
  throws JimiException {
  Image image = Jimi.getImage("myImage.PSD");
  Jimi.putImage(image, "myImage.PNG");
  System.exit(0);
 }
}

Listing 2.

Reading and writing multiple image files

import com.activated.jimi.*;

import java.awt.*;
import java.util.*;

/**
 * A simple example program for reversing the
 * order of frames in a multi-frame image.
 */
public class ImageSeriesReverser
{
 public static void main(String[] args)
 {
  // print usage if wrong arguments are given
  if (args.length != 2) {
   System.err.println("Requires args: <src> <dest>");
   System.exit(1);
 }

 // vector to store loaded images in
 Vector images = new Vector();

  // read the images
  try {
   // create a JimiReader to read the image
   // series from
   JimiReader jr = Jimi.createJimiReader(args[0]);
   // enumerate the images in the series
   Enumeration e = jr.getImageEnumeration();
   // insert them into the vector in reverse
   while (e.hasMoreElements()) {
    Image i = (Image)e.nextElement();
    images.insertElementAt(e, 0);
   }
  }
  // catch exception if the source file
  // is malformed
  catch (JimiException e) {
   System.err.println("Error: " + e);
   System.exit(1);
  }
  // write the images back in reverse
  try {
   // create a JimiWriter for the output file
   JimiWriter jw = Jimi.createJimiWriter(args[1]);
   // pull the images out of the vector and
   // into an array
   Image[] series = new Image[images.size()];
   images.copyInto(series);
   // set the image array as the source for
   // the JimiWriter
   jw.setSource(series);
   // write the images!
   jw.putImage(args[1]);
  }
  // catch exception if the output file
  // can't be written to
  catch (JimiException e) {
   System.err.println("Error: " + e);
   System.exit(1);
  }
  // finished!
  System.exit(0);
 }
}

Listing 3.
Image Processing example method

public JimiBufferedRasterImage flipImage(JimiRasterImage source)
 throws ImageAccessException
{
 // the dimensions of the source image, which
 // are used to create a same-sized target image
 int width = source.getWidth();
 int height = source.getHeight();
 // create an empty target image to populate
// with flipped data
JimiBufferedRasterImage target =
 Jimi.createBufferedRasterImage(width,height);
// a small buffer for pixel data to copy-between
int[] rowBuffer = new int[width];
// the index of the last row of the image
int lastRow = height - 1;
// loop through, copying each row from source to destination
for (int row = 0; row < height; row++) {
 // get the source row
 source.getRowRGB(row, rowBuffer, 0);
 // copy it into the destination image at the
 // opposite location

  target.setRowRGB(lastRow-row, rowBuffer, 0);
 }
 // all finished, the target image is now fully populated
 return target;
}




Printing:-


ava AWT: Printing

Last Updated: December 6, 1999

Purpose
The goal for the AWT printing API is to give developers an easy mechanism to print the AWT
components using native platform facilities. This API is designed for use with the AWT Graphics
model. Developers who prefer to work with Graphics2D should use 2D printing, available in the
java.awt.print package.

The Printing API

The printing API is very simple and consists primarily of one method in class java.awt.Toolkit:


PrintJob getPrintJob(Frame f, String jobtitle, JobAttributes jobAttributes,
PageAttributes pageAttributes)

and a class responsible for encapsulating all the information associated with a printing
request:

           java.awt.PrintJob
The getPrintJob() method in Toolkit will take care of posting any platform specific print
dialogs so that when it returns, the PrintJob object has already been configured to match the
user's request. The JobAttributes and PageAttributes parameters provide the ability to pass in
default attribute values for the print job. This allows the printing attributes appropriate for a
particular application to be stored and applied in individual circumstances. If the user changes
the default attributes in the print dialog, those changes are saved into the JobAttributes and
PageAttributes instances passed to the method (so the program can choose to store those new
defaults if desired).

The PrintJob object provides access to the relevant printing properties chosen by the user
(page size, etc) as well as the print graphics contexts used to transparently render to the print
device.

Print Graphics Context

The print graphics context is provided by an interface:

java.awt.PrintGraphics

The PrintJob object provides the method to obtain a handle to an object which is a subclass of
Graphics AND implements the PrintGraphics interface:

Graphics getGraphics()

Since this object is a subclass of the Graphics class, it can simply be passed into existing
paint() or print() methods (which use the standard Graphics drawing methods) and the
underlying AWT implementation takes care of translating those calls to the appropriate print
device (this is straightforward on Mac/Windows which support graphic print devices; on
Solaris, a PostScript graphics object is required to generate appropriate PostScript).

It is often the case that from within a paint() or print() method, your program may want to
detect whether it is rendering to the screen or to a print device (for example it would not
necessarily want to print `highlighted' text which has been selected by the user). Since the
graphics object returned from the PrintJob.getGraphics() method implements the
PrintGraphics interface, this can easily be detected with the following test:

          public void paint(Graphics g) {
                  if (g instanceof PrintGraphics)
                          // printing is occurring
                          ...

The primary method in the PrintGraphics interface is a method to obtain a handle to the
associated PrintJob object:

PrintJob getPrintJob()

Pagination

It is the program's responsibility to handle pagination. Each call to getGraphics() will return a print
graphics context for a single page; when the program calls dispose() on the print graphics context,
that page is flushed to the printer. The program must take care of determining appropriate page
content and page breaking, given the specified page dimensions and resolution.

These printing attributes can be obtained by the following methods on java.awt.PrintJob:

Dimension getPageDimension()
int getPageResolution()

Printing Hierarchies of Components

If a program needs to print an entire containment hierarchy of AWT components (i.e. a Panel and
any nested controls/containers within it), it should call the following java.awt.Component method
on the root of the containment hierarchy (passing in the appropriate print graphics context):

public void printAll(Graphics g)

Calling this method will result in the complete traversal of the containment hierarchy such
that the print() method will be called on all descendent components. The default
implementation of the print() method simply calls paint(), so if a program has created a
component which renders itself in the paint() method, printing should work "automagically".
Note that all the base AWT components (Button, Scrollbar, etc.) are capable of printing
themselves when their printAll() method is called (even though their rendering does not take
place in the paint() method).

Print Dialogs

Although it is important for some programs to either extend or create their own print dialogs, this
capability is currently not available via AWT printing, nor via 2D printing.

Security

Because it was considered dangerous to allow potentially untrusted applets to initiate print job
requests (and potentially quietly print anything devious to the printer that they desire) the initiation
of a PrintJob (via Toolkit.getPrintJob) is defined to be an operation bound by the Applet security
restrictions implemented in a SecurityManager method. In addition, while printing may be
permitted, access to the file system may not. In such a case, requests to print to a file
programmatically will generate an exception and the user will be unable to select print to file.

It's important to note that this restriction does not limit applets' capability to render using a
PrintGraphics object returned from a PrintJob; it just disallows untrusted applets to initiate
the job. A more reasonable policy will be provided when the Java security architecture allows
more customization.

Sample Code
A VERY simple example of how a print job can be initiated to print an AWT component:


import java.awt.*;
import java.awt.event.*;

public class PrintingTest extends Frame implements ActionListener {

    PrintCanvas canvas;

    public PrintingTest() {
        super("Printing Test");
        canvas = new PrintCanvas();
        add("Center", canvas);

        Button b = new Button("Print");
        b.setActionCommand("print");
        b.addActionListener(this);
        add("South", b);

        pack();
    }

    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
        if (cmd.equals("print")) {
            PrintJob pjob = getToolkit().getPrintJob(this,
                               "Printing Test", null, null);

            if (pjob != null) {
                Graphics pg = pjob.getGraphics();

                  if (pg != null) {
                      canvas.printAll(pg);
                      pg.dispose(); // flush page
                  }
                  pjob.end();

            }
        }
    }

    public static void main(String args[]) {
        PrintingTest test = new PrintingTest();
        test.show();
    }
}

class PrintCanvas extends Canvas {

    public Dimension getPreferredSize() {
        return new Dimension(100, 100);
    }

    public void paint(Graphics g) {
        Rectangle r = getBounds();

        g.setColor(Color.yellow);
        g.fillRect(0, 0, r.width, r.height);

        g.setColor(Color.blue);
        g.drawLine(0, 0, r.width, r.height);

        g.setColor(Color.red);
        g.drawLine(0, r.height, r.width, 0);
     }
}


TheClipboard:-


Class Clipboard
java.lang.Object
    java.awt.datatransfer.Clipboard


public class Clipboard
extends Object

A class that implements a mechanism to transfer data using cut/copy/paste operations.

FlavorListeners    may be registered on an instance of the Clipboard class to be notified
about changes to the set of DataFlavors available on this clipboard (see
addFlavorListener(java.awt.datatransfer.FlavorListener)).

See Also:

         Toolkit.getSystemClipboard(), Toolkit.getSystemSelection()




Field Summary
       protected contents
    Transferable


      protected owner
 ClipboardOwner




Constructor Summary
Clipboard(String name)
     Creates a clipboard object.




Method Summary
                void addFlavorListener(FlavorListener listener)
                            Registers the specified FlavorListener to receive FlavorEvents
                       from this clipboard.

      DataFlavor[] getAvailableDataFlavors()
                       Returns an array of DataFlavors in which the current contents of this
                       clipboard can be provided.

      Transferable getContents(Object requestor)
                             Returns a transferable object representing the current contents of the
                       clipboard.

              Object getData(DataFlavor flavor)
                             Returns an object representing the current contents of this clipboard
                       in the specified DataFlavor.

 FlavorListener[] getFlavorListeners()
                             Returns an array of all the FlavorListeners currently registered on
                       this Clipboard.

              String getName()
                            Returns the name of this clipboard object.

            boolean isDataFlavorAvailable(DataFlavor flavor)
                            Returns whether or not the current contents of this clipboard can be
                       provided in the specified DataFlavor.

                void removeFlavorListener(FlavorListener listener)
                         Removes the specified FlavorListener so that it no longer receives
                       FlavorEvents from this Clipboard.

                void setContents(Transferable contents, ClipboardOwner owner)
                            Sets the current contents of the clipboard to the specified transferable
                       object and registers the specified clipboard owner as the owner of the new
                       contents.




Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString,
wait, wait, wait
Field Detail

owner
protected ClipboardOwner owner



contents
protected Transferable contents

Constructor Detail

Clipboard
public Clipboard(String name)
     Creates a clipboard object.

     See Also:

     Toolkit.getSystemClipboard()


Method Detail

getName
public String getName()
     Returns the name of this clipboard object.

     See Also:

     Toolkit.getSystemClipboard()




setContents
public void setContents(Transferable contents,
                        ClipboardOwner owner)
     Sets the current contents of the clipboard to the specified transferable object and registers
     the specified clipboard owner as the owner of the new contents.

     If there is an existing owner different from the argument owner, that owner is notified
     that it no longer holds ownership of the clipboard contents via an invocation of
     ClipboardOwner.lostOwnership() on that owner. An implementation of
     setContents() is free not to invoke lostOwnership() directly from this method.
     For example, lostOwnership() may be invoked later on a different thread. The same
     applies to FlavorListeners registered on this clipboard.

     The method throws IllegalStateException if the clipboard is currently
     unavailable. For example, on some platforms, the system clipboard is unavailable
     while it is accessed by another application.

     Parameters:

     contents - the transferable object representing the clipboard content

     owner - the object which owns the clipboard content

     Throws:

     IllegalStateException - if the clipboard is currently unavailable

     See Also:

     Toolkit.getSystemClipboard()




getContents
public Transferable getContents(Object requestor)
     Returns a transferable object representing the current contents of the clipboard. If the
     clipboard currently has no contents, it returns null. The parameter Object requestor is not
     currently used. The method throws IllegalStateException if the clipboard is currently
     unavailable. For example, on some platforms, the system clipboard is unavailable while it is
     accessed by another application.

     Parameters:

     requestor - the object requesting the clip data (not used)

     Returns:

     the current transferable object on the clipboard

     Throws:

     IllegalStateException - if the clipboard is currently unavailable

     See Also:

     Toolkit.getSystemClipboard()




getAvailableDataFlavors
public DataFlavor[] getAvailableDataFlavors()
      Returns an array of DataFlavors in which the current contents of this clipboard can be
       provided. If there are no DataFlavors available, this method returns a zero-length array.

       Returns:

       an array of DataFlavors in which the current contents of this clipboard can be provided

       Throws:

       IllegalStateException - if this clipboard is currently unavailable

       Since:

       1.5




isDataFlavorAvailable
public boolean isDataFlavorAvailable(DataFlavor flavor)
       Returns whether or not the current contents of this clipboard can be provided in the
       specified DataFlavor.

       Parameters:

       flavor - the requested DataFlavor for the contents

       Returns:

       true if the current contents of this clipboard can be provided in the specified DataFlavor;
       false otherwise

       Throws:

       NullPointerException - if flavor is null

       IllegalStateException - if this clipboard is currently unavailable

       Since:

       1.5




getData
public Object getData(DataFlavor flavor)
               throws UnsupportedFlavorException,
                      IOException
       Returns an object representing the current contents of this clipboard in the specified
       DataFlavor. The class of the object returned is defined by the representation class of
       flavor.

       Parameters:

       flavor - the requested DataFlavor for the contents

       Returns:

       an object representing the current contents of this clipboard in the specified DataFlavor

       Throws:

       NullPointerException - if flavor is null

       IllegalStateException - if this clipboard is currently unavailable

       UnsupportedFlavorException - if the requested DataFlavor is not available

       IOException - if the data in the requested DataFlavor can not be retrieved

       Since:

       1.5

       See Also:

       DataFlavor.getRepresentationClass()




addFlavorListener
public void addFlavorListener(FlavorListener listener)
      Registers the specified FlavorListener to receive FlavorEvents from this clipboard. If
       listener is null, no exception is thrown and no action is performed.

       Parameters:

       listener - the listener to be added

       Since:

       1.5

       See Also:

       removeFlavorListener(java.awt.datatransfer.FlavorListener),
       getFlavorListeners(), FlavorListener, FlavorEvent
removeFlavorListener
public void removeFlavorListener(FlavorListener listener)
      Removes the specified FlavorListener so that it no longer receives FlavorEvents from
         this Clipboard. This method performs no function, nor does it throw an exception, if the
         listener specified by the argument was not previously added to this Clipboard. If
         listener is null, no exception is thrown and no action is performed.

         Parameters:

         listener - the listener to be removed

         Since:

         1.5

         See Also:

         addFlavorListener(java.awt.datatransfer.FlavorListener),
         getFlavorListeners(), FlavorListener, FlavorEvent




getFlavorListeners
public FlavorListener[] getFlavorListeners()
      Returns an array of all the FlavorListeners currently registered on this Clipboard.

         Returns:

         all of this clipboard's FlavorListeners or an empty array if no listeners are currently
         registered




In Java, there are actually two kinds of Clipboard - system and local. The following example
uses the system Clipboard. It corresponds to the usual idea of sharing data between
otherwise independent applications running on the same computer.

Local Clipboards are visible only within a single Java application. They are created by
simply passing a name to the Clipboard constructor.


import    java.awt.datatransfer.Clipboard;
import    java.awt.datatransfer.ClipboardOwner;
import    java.awt.datatransfer.Transferable;
import    java.awt.datatransfer.StringSelection;
import    java.awt.datatransfer.DataFlavor;
import    java.awt.datatransfer.UnsupportedFlavorException;
import    java.awt.Toolkit;
import    java.io.*;

public final class TextTransfer implements ClipboardOwner {
    public static void main (String... aArguments ){
      TextTransfer textTransfer = new TextTransfer();

    //display what is currently on the clipboard
    System.out.println("Clipboard contains:" +
textTransfer.getClipboardContents() );

    //change the contents and then re-display
    textTransfer.setClipboardContents("blah, blah, blah");
    System.out.println("Clipboard contains:" +
textTransfer.getClipboardContents() );
  }

     /**
     * Empty implementation of the ClipboardOwner interface.
     */
     public void lostOwnership( Clipboard aClipboard, Transferable aContents)
{
         //do nothing
     }

    /**
    * Place a String on the clipboard, and make this class the
    * owner of the Clipboard's contents.
    */
    public void setClipboardContents( String aString ){
       StringSelection stringSelection = new StringSelection( aString );
       Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
       clipboard.setContents( stringSelection, this );
    }

    /**
    * Get the String residing on the clipboard.
    *
    * @return any text found on the Clipboard; if none found, return an
    * empty String.
    */
    public String getClipboardContents() {
       String result = "";
       Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
       //odd: the Object param of getContents is not currently used
       Transferable contents = clipboard.getContents(null);
       boolean hasTransferableText =
         (contents != null) &&
         contents.isDataFlavorSupported(DataFlavor.stringFlavor)
       ;
       if ( hasTransferableText ) {
         try {
           result = (String)contents.getTransferData(DataFlavor.stringFlavor);
         }
         catch (UnsupportedFlavorException ex){
           //highly unlikely since we are using a standard DataFlavor
           System.out.println(ex);
           ex.printStackTrace();
         }
         catch (IOException ex) {
           System.out.println(ex);
           ex.printStackTrace();
         }
       }
        return result;
    }
}



An example run of this class :

>java -cp . TextTransfer




DRAG AND DROP IN AWT:-

Java 2 (formerly JDK 1.2) introduced the ability to transfer data using the familiar drag and
drop (D&D) metaphor. In Java 2, D&D utilizes the underlying data-transfer mechanism
introduced in JDK 1.1 (java.awt.datatransfer) for use with the clipboard. Although this
article discusses D&D operations in the context of GUI components, the specification
includes no restrictions that prevent direct programmatic operations.

To develop the D&D metaphor, Java 2 defines several new classes in package
java.awt.dnd. Please note: The GUI components used in this article are Swing components.
In actuality, any subclass of java.awt.Component may be used.

First, we'll look at how a GUI component representing the data source of a D&D operation
maintains an association with a java.awt.dnd.DropSource object.

Second, we'll examine how another GUI component representing the destination of the data
of a D&D operation maintains an association with a java.awt.dnd.DropTarget object.

Finally, we'll wrap up with a java.awt.datatransfer.Transferable object that
encapsulates the data transferred between the DragSource and DropTarget objects.

To download the source code in either zip or tar formats, see Resources.




DataFlavors and actions

When the Transferable object encapsulates data, it makes the data available to DropTarget
in a variety of DataFlavors. For a local transfer within the same JVM (Java virtual
machine), Transferable provides an object reference.
However, for transfers to another JVM or to the native system, this wouldn't make any sense,
so a DataFlavor using a java.io.InputStream subclass usually is provided. (While a
discussion of data transfer classes is beyond the scope of this article, you will find a linked
list of previous JavaWorld articles on this topic in the Resources section below.)

When invoking a drag and drop operation, you may request various drag and drop actions.
The DnDConstants class defines the class variables for the supported actions:

      ACTION_NONE -- no action taken
      ACTION_COPY -- the DragSource leaves the data intact
      ACTION_MOVE -- the DragSource deletes the data upon successful completion of the drop
      ACTION_COPY or ACTION_MOVE -- the DragSource will perform either action requested by
       the DropTarget
      ACTION_LINK or ACTION_REFERENCE -- a data change to either the source or the destination
       propagates to the other location




Creating a draggable component

For a GUI component to act as the source of a D&D operation, it must be associated with five
objects:

      java.awt.dnd.DragSource
      java.awt.dnd.DragGestureRecognizer
      java.awt.dnd.DragGestureListener
      java.awt.datatransfer.Transferable
      java.awt.dnd.DragSourceListener




The DragSource

A common way to obtain a DragSource object is to use one instance per JVM. Class method
DragSource.getDefaultDragSource will obtain a shared DragSource object that is used
for the lifetime of the JVM. Another option is to provide one DragSource per instance of the
Component class. With this option, however, you accept responsibility for implementation.

   
                                              Section D
TOPICS TO BE COVERED IN THIS SECTION:-
JAVABEANS COMPONENTS

      Beans,
      The Bean-Writing Process,
      Using Beans to Build an Application,
      Naming Patterns for Bean
      Components and Events Bean Property Tubes Beaninfo Classes Property Editors
       Cuatomizes

SECURITY

      Class Loaders
      , Bytecode Verification
      , Security Managers and Permissions
      , Digital Signatures,
      Code Signing,
      Encryption

                                 Java beans components

Beans:-

A Bean is a JavaBeans component. Beans are independent, reusable software modules. Beans
may be visible objects, like AWT components, or invisible objects, like queues and stacks. A
builder/integration tool manipulates Beans to create applets and applications.

Exercise

   1. Creating the First Bean with Kaidi

Beans Architecture

Beans consist of three things:

      Events
      Properties
      Methods

Also, since Beans rely on their state, they need to be able to be persistent over time.
JavaBeans components are Java classes that can be easily reused and composed together into
applications. Any Java class that follows certain design conventions can be a JavaBeans
component.

JavaServer Pages technology directly supports using JavaBeans components with JSP
language elements. You can easily create and initialize beans and get and set the values of
their properties. This chapter provides basic information about JavaBeans components and
the JSP language elements for accessing beans in your JSP pages. For further information
about the JavaBeans component model,

JavaBeans component design conventions govern the properties of the class, and govern the
public methods that give access to the properties.

A JavaBeans component property can be

      Read/write, read-only, or write-only
      Simple, which means it contains a single value, or indexed, which means it represents an
       array of values

There is no requirement that a property be implemented by an instance variable; the property
must simply be accessible using public methods that conform to certain conventions:

      For each readable property, the bean must have a method of the form PropertyClass
       getProperty() { ... }
      For each writable property, the bean must have a method of the form
       setProperty(PropertyClass pc) { ... }

In addition to the property methods, a JavaBeans component must define a constructor that
takes no parameters.

The Duke's Bookstore application JSP pages enter.jsp, bookdetails.jsp, catalog.jsp,
and showcart.jsp use the database.BookDB and database.BookDetails JavaBeans
components. BookDB provides a JavaBeans component front end to the enterprise bean
BookDBEJB. Both beans are used extensively by bean-oriented custom tags (see Tags That
Define Scripting Variables). The JSP pages showcart.jsp and cashier.jsp use
cart.ShoppingCart to represent a user's shopping cart.

The JSP pages catalog.jsp, showcart.jsp, and cashier.jsp use the util.Currency
JavaBeans component to format currency in a locale-sensitive manner. The bean has two
writable properties, locale and amount, and one readable property, format. The format
property does not correspond to any instance variable, but returns a function of the locale
and amount properties.

public class Currency {
   private Locale locale;
   private double amount;
   public Currency() {
      locale = null;
      amount = 0.0;
   }
   public void setLocale(Locale l) {
      locale = l;
     }
     public void setAmount(double a) {
        amount = a;
     }
     public String getFormat() {
        NumberFormat nf =
           NumberFormat.getCurrencyInstance(locale);
        return nf.format(amount);
     }
}




Creating and Using a JavaBeans Component
You declare that your JSP page will use a JavaBeans component using either one of the
following formats:

<jsp:useBean id="beanName"
   class="fully_qualified_classname" scope="scope"/>


or

<jsp:useBean id="beanName"
   class="fully_qualified_classname" scope="scope">
   <jsp:setProperty .../>
</jsp:useBean>


The second format is used when you want to include jsp:setProperty statements,
described in the next section, for initializing bean properties.

The jsp:useBean element declares that the page will use a bean that is stored within and
accessible from the specified scope, which can be application, session, request, or page.
If no such bean exists, the statement creates the bean and stores it as an attribute of the scope
object (see Using Scope Objects). The value of the id attribute determines the name of the
bean in the scope and the identifier used to reference the bean in other JSP elements and
scriptlets.




Setting JavaBeans Component Properties
There are two ways to set JavaBeans component properties in a JSP page: with the
jsp:setProperty element or with a scriptlet

<% beanName.setPropName(value); %>
The syntax of the jsp:setProperty element depends on the source of the property value.
Table 12-1 summarizes the various ways to set a property of a JavaBeans component using
the jsp:setProperty element.

                       Table 12-1 Setting JavaBeans Component Properties


                Value Source                                  Element Syntax

                                           <jsp:setProperty name="beanName"
String constant                            property="propName" value="string
                                           constant"/>


                                           <jsp:setProperty name="beanName"
Request parameter
                                           property="propName" param="paramName"/>


                                           <jsp:setProperty name="beanName"
                                           property="propName"/>
Request parameter name matches bean
property
                                           <jsp:setProperty name="beanName"
                                           property="*"/>


                                           <jsp:setProperty name="beanName"
Expression                                 property="propName"
                                           value="<%= expression %>"/>


1. beanName must be the same as that specified for the id attribute in a useBean element.
2. There must be a setPropName method in the JavaBeans component.
3. paramName must be a request parameter name.



A property set from a constant string or request parameter must have a type listed in Table
12-2. Since both a constant and request parameter are strings, the Web container
automatically converts the value to the property's type; the conversion applied is shown in the
table. String values can be used to assign values to a property that has a PropertyEditor
class. When that is the case, the setAsText(String) method is used. A conversion failure
arises if the method throws an IllegalArgumentException. The value assigned to an
indexed property must be an array, and the rules just described apply to the elements.

                       Table 12-2 Valid Value Assignments


   Property Type                      Conversion on String Value


Bean property           Uses setAsText(string-literal)
boolean or Boolean As indicated in java.lang.Boolean.valueOf(String)


byte or Byte          As indicated in java.lang.Byte.valueOf(String)


char or Character     As indicated in java.lang.String.charAt(0)


double or Double      As indicated in java.lang.Double.valueOf(String)


int or Integer        As indicated in java.lang.Integer.valueOf(String)


float or Float        As indicated in java.lang.Float.valueOf(String)


long or Long          As indicated in java.lang.Long.valueOf(String)


short or Short        As indicated in java.lang.Short.valueOf(String)

Object                new String(string-literal)



You would use a runtime expression to set the value of a property whose type is a compound
Java programming language type. Recall from the section Expressions that a JSP expression
is used to insert the value of a scripting language expression, converted into a String, into
the stream returned to the client. When used within a setProperty element, an expression
simply returns its value; no automatic conversion is performed. As a consequence, the type
returned from an expression must match or be castable to the type of the property.

The Duke's Bookstore application demonstrates how to use the setProperty element and a
scriptlet to set the current book for the database helper bean. For example,
bookstore3/bookdetails.jsp uses the form

<jsp:setProperty name="bookDB" property="bookId"/>


whereas bookstore2/bookdetails.jsp uses the form

<% bookDB.setBookId(bookId); %>


The following fragments from the page bookstore3/showcart.jsp illustrate how to
initialize a currency bean with a Locale object and amount determined by evaluating request-
time expressions. Because the first initialization is nested in a useBean element, it is only
executed when the bean is created.

<jsp:useBean id="currency" class="util.Currency"
   scope="session">
   <jsp:setProperty name="currency" property="locale"
      value="<%= request.getLocale() %>"/>
</jsp:useBean>

<jsp:setProperty name="currency" property="amount"
   value="<%=cart.getTotal()%>"/>



Retrieving JavaBeans Component Properties
There are several ways to retrieve JavaBeans component properties. Two of the methods (the
jsp:getProperty element and an expression) convert the value of the property into a
String and insert the value into the current implicit out object:

        <jsp:getProperty name="beanName" property="propName"/>
        <%= beanName.getPropName() %>

For both methods, beanName must be the same as that specified for the id attribute in a
useBean element, and there must be a getPropName method in the JavaBeans component.

If you need to retrieve the value of a property without converting it and inserting it into the
out object, you must use a scriptlet:

<% Object o = beanName.getPropName(); %>


Note the differences between the expression and the scriptlet: the expression has an = after
the opening % and does not terminate with a semicolon, as does the scriptlet.

The Duke's Bookstore application demonstrates how to use both forms to retrieve the
formatted currency from the currency bean and insert it into the page. For example,
bookstore3/showcart.jsp uses the form

<jsp:getProperty name="currency" property="format"/>


whereas bookstore2/showcart.jsp uses the form

<%= currency.getFormat() %>


The Duke's Bookstore application page bookstore2/showcart.jsp uses the following
scriptlet to retrieve the number of books from the shopping cart bean and open a conditional
insertion of text into the output stream:

<%
     // Print a summary of the shopping cart
     int num = cart.getNumberOfItems();
     if (num > 0) {
%>


Although scriptlets are very useful for dynamic processing, using custom tags (see
Chapter 13) to access object properties and perform flow control is considered to be a better
approach. For example, bookstore3/showcart.jsp replaces the scriptlet with the following
custom tags:

<bean:define id="num" name="cart" property="numberOfItems" />
<logic:greaterThan name="num" value="0" >


Figure 12-1 summarizes where various types of objects are stored and how those objects can
be accessed from a JSP page. Objects created by the jsp:useBean tag are stored as attributes
of the scope objects and can be accessed by jsp:[get|set]Property tags and in scriptlets
and expressions. Objects created in declarations and scriptlets are stored as variables of the
JSP page's servlet class and can be accessed in scriptlets and expressions.




Figure 12-1 Accessing Objects from a JSP Page



The Bean-Writing Process:-


Writing a SimpleBean
In this section you will learn more about Beans and the BeanBox by

      Creating a simple Bean
      Compiling and saving the Bean into a Java Archive (JAR) file
        Loading the Bean into the ToolBox
        Dropping a Bean instance into the BeanBox
        Inspecting the Bean's properties, methods, and events
        Generating an introspection report

Your Bean will be named SimpleBean. Here are the steps to create it and view it in the
BeanBox:

   1. Write the SimpleBean code. Put it in a file named SimpleBean.java, in the directory of
      your choice. Here's the code:
   2.
   3.
   4. import java.awt.*;
   5. import java.io.Serializable;
   6.
   7. public class SimpleBean extends Canvas
   8.                       implements Serializable{
   9.
   10.    //Constructor sets inherited properties
   11.    public SimpleBean(){
   12.      setSize(60,40);
   13.      setBackground(Color.red);
   14.    }
   15.
   16. }

         SimpleBean    extends the java.awt.Canvas component. SimpleBean also implements
         the java.io.Serializable interface, a requirement for all Beans. SimpleBean sets the
         background color and component size.

   17. Make sure the CLASSPATH environment variable is set to point to all needed .class (or
       .jar) files. Here are some URLs that will help you to set CLASSPATH correctly:
          o The Managing Source and Class Files lesson gives good advice on how and when to
               set your CLASSPATH.
          o The JDK Tool Reference Page provides complete CLASSPATH information for both
               Windows and Solaris platforms.
   18. Compile the Bean:
   19.             javac SimpleBean.java


         This produces the class file SimpleBean.class

   20. Create a manifest file. Use your favorite text editor to create a file, we'll call it
       manifest.tmp, that contains the following text:
   21.           Name: SimpleBean.class
   22.           Java-Bean: True


   23. Create the JAR file. The JAR file will contain the manifest and the SimpleBean class file:
   24.           jar cfm SimpleBean.jar manifest.tmp SimpleBean.class


         See the JAR File Format trail, and the JDK JAR file documentation for complete information
         on JAR files.
   25. Load the JAR file into the ToolBox. Select the File|LoadJar... menu item. This will bring up a
       file browser. Navigate to the SimpleBean.jar location and select it. SimpleBean will
       appear at the bottom of the ToolBox. (Note that when the BeanBox is started, all Beans in
       JAR files in the beans/jars directory are automatically loaded into the ToolBox).
   26. Drop a SimpleBean instance into the BeanBox. Click on the word SimpleBean in the
       ToolBox. The cursor will change to a crosshair. Move the cursor to a spot within the BeanBox
       and click. SimpleBean will appear as a painted rectangle with a hatched border. This border
       means that SimpleBean is selected. The SimpleBean properties will appear in the
       Properties sheet.

You can resize SimpleBean, because it inherits from Canvas, by dragging a corner. You will
see the cursor change to a right angle when over a corner. You can also reposition
SimpleBean within the BeanBox by dragging on any non-corner portion of the hatched
border. You will see the cursor change to crossed arrows when in position to move the Bean.

SimpleBean Makefiles

Below are two makefiles (Unix and Windows) set up to create SimpleBean.



# gnumake file

CLASSFILES= SimpleBean.class

JARFILE= SimpleBean.jar

all: $(JARFILE)

# Create a JAR file with a suitable manifest.
$(JARFILE): $(CLASSFILES) $(DATAFILES)
        echo "Name: SimpleBean.class" >> manifest.tmp
        echo "Java-Bean: True" >> manifest.tmp
        jar cfm $(JARFILE) manifest.tmp *.class
        @/bin/rm manifest.tmp

# Compile the sources
%.class: %.java
        export CLASSPATH; CLASSPATH=. ; \
        javac $<

# make clean
clean:
        /bin/rm -f *.class
        /bin/rm -f $(JARFILE)




Here is the Windows nmake version:



# nmake file
CLASSFILES= simplebean.class

JARFILE= simplebean.jar
all: $(JARFILE)

# Create a JAR file with a suitable manifest.

$(JARFILE): $(CLASSFILES) $(DATAFILES)
        jar cfm $(JARFILE) <<manifest.tmp *.class
Name: SimpleBean.class
Java-Bean: True
<<

.SUFFIXES: .java .class

{sunw\demo\simple}.java{sunw\demo\simple}.class :
        set CLASSPATH=.
        javac $<

clean:
           -del sunw\demo\simple\*.class
           -del $(JARFILE)



You can use these makefiles as templates for creating your own Bean makefiles. The
example Bean makefiles, in the beans/demo directory, also show you how to use makefiles
to build and maintain your Beans.

Inspecting SimpleBean Properties and Events

The Properties sheet displays the selected Bean's properties. With SimpleBean selected, the
Properties sheet displays four propeties: foreground, background, font, and name. We
declared no properties in SimpleBean (see the Properties section to learn how to declare
properties), so these are properties inherited from Canvas. Clicking on each property brings
up a property editor. The BeanBox provides default property editors for the primitive types,
plus Font and Color types. You can find the sources for these property editors in
beans/apis/sun/beans/editors.

Beans communicate with other Beans by sending and receiving event notifications. To see
which events SimpleBean can send, choose the Edit|Events BeanBox menu item. A list of
events, grouped by the Java interface in which the event method is declared, will be
displayed. Under each interface group is a list of event methods. These are all inherited from
Canvas.

You will learn more about properties and events in upcoming sections.

Generating Bean Introspection Reports

Introspection is the process of discovering a Bean's design-time features by one of two
methods:

        Low-level reflection, which uses design patterns to discover your Bean's features
        By examining an associated bean information class that explicitly describes your Bean's
         features.
You can generate a Bean introspection report by choosing the the Edit|Report menu item. The
report lists Bean events, properties, and methods, and their characteristics.

By default Bean reports are sent to the java interpreter's standard output, which is the
window where you started the BeanBox. You can redirect the report to a file by changing the
java interpreter command in beanbox/run.sh or run.bat to:

java sun.beanbox.BeanBoxFrame > beanreport.txt




Using Beans to Build an Application:-

Step 1 - Create a library
From a fresh opening of netbeans, do:
file->new project
for category choose 'java'
for project choose 'java class library'
Then choose an appropriate location and name for your library. I chose grlib1 for the name.


Step 2 - Create an empty class
file->new file
for category choose 'java'
for file type choose 'Java Class'
click 'next'
Enter an appropriate class name. I chose 'grbuttonx'.
Leave everything else untouched.


Step 3 - Make code changes
       All beans must contain a constructor with no parameters. My constructor initializes my only
        property/member variable (img).
       All beans must contain 'implements Serializable'. You don't need to override any of these
        functions but you have to have that in your class definition. Serializable lets the IDE save
        your property values during design time.
       Any properties of your bean must have get and set functions if you want to have them show
        up in property lists. I only have one property and it is write only so I created a function called
        'setImage()'.
       Beans apparently need to meet security considerations and so probably won't let you do
        certain things like access local files.

I wanted a button with a cool image so I inherited from JButton. This gave me all kinds of properties
and it already serializes everything I care about (don't care about the image as this is loaded in
runtime). This is very basic implementation - there is no focus image, no down image, no roll over
image. Here's my code:
package grlib1;
import javax.swing.JButton;
import java.awt.*;
import java.io.Serializable;


/**
 * @author gr@gr5.org
 */
public class grbuttonx extends JButton implements Serializable {
    private Image img;
    public grbuttonx() {
        img=null;
    }

     public void setImage(Image i) {
         img=i;
     }

         public void paint(Graphics g) {
            if (img != null)
                g.drawImage(img, 0, 0,null);
            else {
                g.setColor(Color.red);
                Dimension size = getSize();
                g.fillOval(0, 0, size.width, size.height);
                }
     }

}



Step 4 - Fix manifest to show this is a bean library

First get to the files tab of your project (ctrl/2 should get you there). In the top level of the tree view
it shows your projects. The next level down should have a file called build.xml. Click the plus sign
next to it. Then double click any element below build.xml. You should be now editing a file called
build-impl.xml.

Search for "<manifest" (I include the open < to simplify the search). There should only be
one such tag in the file and you should be in the jar building section (scroll up to see the next
comment block if you want to double check).

There should already be 2 attributes in the manifest. Add one called Java-Bean as shown:


                 <manifest>
                     <attribute name="Main-Class" value="${main.class}"/>
                     <attribute name="Class-Path" value="${jar.classpath}"/>
                     <attribute name="Java-Bean" value="true"/>
                 </manifest>
Now build your library!


Step 5 - test it!

Create a new project or open an existing project. Open a frame or a form or something that allows
you to drop buttons onto it. Get into design mode so you can see the palette window (if you can't
see it you can open the palette window and you might want to pin it open with the pin in the title
bar).

In menu system do: tools -> palette -> Swing/AWT Components
there should be 3 buttons. Eventually you might want to choose Add from JAR but we will
do:
Add From Project...
There may be a delay at this point. Navigate if necessary and choose your library project
created in step 1. Click next.
Your component should show up. Click it and click 'next' again.
Select a folder to put your bean into - I always choose "Beans". Click 'finish'.

Now you should see your been in the pallette near the bottom in the Beans section. Open up
the beans section if it isn't already. Click your bean and then click in your window to place it.
That's it.

Step 6 - debugging

If you keep both projects open (the library and the project) you can usually make edits in either
place and breakpoints in either place. I recommend keeping the non-library as the default/main
project which runs if you hit F6 and keeping a window on your bean for edits and breakpoints.
Before building your application, build just the bean with the bean code open and hit F9 key to build
it. Occasionally you will want to build the whole library. I don't know the IDE well so I choose the
library as the main project, build it, then go back to the application project. Occasionally I go
completely out of the application and reopen it to get proper design time handling of my bean but
usually I don't care if it looks like the pre-edited bean. Breakpoints work great.

Good luck! If this is useful to you please add a link to this page from one of your web pages
so that this page will get higher on search order for site like google (but only do it if you like
this document). Also please email me - I always like getting comments/suggestions/whatever.
Really. If I get too much email I will just remove this link. You can email me here.

Naming Patterns for Bean:-

he specification of the JavaBean component model by Sun defines a
set of conventions
• naming methods, event, properties
• also called Design Patterns (unfortunate misuse of the term “design patterns” should
have been called “naming patterns”)
! Bean‘s programmer follows these standards in naming elements of the
bean
! Visual tools use pre-defined Introspector classes to dynamically extract
the BeanInfo metadata based on these conventions
26




Naming Patterns and Conventions
As we've seen, beanbox programs may rely on introspection of a bean to determine the list of
properties, events, and methods it supports. In order for this to work, bean developers must
follow a set of standard naming conventions, sometimes referred to as JavaBeans "design
patterns." These patterns specify, for example, that the getter and setter accessor methods for
a property should begin with get and set. Not all of the patterns are absolute requirements. If
a bean has accessor methods with different names, it is possible to use a
PropertyDescriptor object, specified in a BeanInfo class, to specify the accessor methods
for the property. Note, however, that although an accessor method name is not required to
follow the pattern, the method is required to have the exact type signature specified by the
pattern.

This section lists the design patterns for bean properties, events, and methods. It also lists
other conventions and requirements that you should keep in mind when developing beans.

Java Bean Patterns

Beans
class name:

          Any

superclass:

          Any

constructor:

          Must have a no-argument constructor, or a serialized template file

packaging:

          JAR file manifest entry specifies Java-Bean: True

Properties (property p of type T)
getter:

          public T getP()
setter:

          public void setP(T value)

Boolean Properties (property p of type boolean)
getter:

          public boolean getP()
(boolean value)
          or public boolean is P() setter:

          public void setP

Indexed Properties (property p of type T[])
array getter:

          public T[] getP()
array setter:

          public void setP(T[] value)
element getter:

          public T getP(int index)
element setter:

          public void setP(int index, T value)

Bound Properties (property p of type T)
getter:

          Same as regular property

setter:

          Same as regular property

listeners:

          One event listener list for all bound properties of a bean

listener registration:

          public void addPropertyChangeListener (PropertyChangeListener l)
listener removal:

          public void removePropertyChangeListener (PropertyChangeListener l)

Constrained Properties (property p of type T)
getter:

          Same as regular property

setter:

          public void setP(T value)
                                                           throws PropertyVetoException
listeners:

          One event listener list for all constrained properties of a bean

listener registration:
        public void addVetoableChangeListener (VetoableChangeListener l)
listener removal:

        public void removeVetoableChangeListener
                    (VetoableChangeListener l)

Events (event named E)
event class name:

        EEvent
listener name:

        EListener
listener methods:

        public void methodname(EEvent e)
listener registration:

        public void addEListener(EListener l)
listener removal:

        public void removeEListener(EListener l)

Unicast Events (event named E only one listener allowed)
listener registration:

        public void addEListener(EListener l)
               throws TooManyListenersException
listener removal:

        public void removeEListener(EListener l)

Methods
method name:

        Any

method args:

        Any; some tools only recognize no-argument methods

BeanInfo Classes (for bean B)
class name:

        BBeanInfo

Property Editors (for properties of type T)
class name:

        TEditor
constructor:

        Must have a no-argument constructor
Property Editors (for individual properties)
class name:

        Any; register via PropertyDescriptor

constructor:

        Must have a no-argument constructor

Customizers (for bean B)
class name:

        Any; register via BeanDescriptor (BCustomizer by convention)

superclass:

        Must be a component; typically extends Panel

constructor:

        Must have a no-argument constructor

Documentation File (for bean B)
default docs:

        B.html
localized docs:

        locale/B.html




Components and Events Bean Property Tubes Beaninfo Classes Property Editors
Cuatomizes:-



                                         SECURITY:-

Class Loaders:-


Security and the class loader architecture
A look at the role played by class loaders in the JVM's overall security model

By Bill Venners, JavaWorld.com, 09/01/97

       Print
       Feedback
       Add a comment

. What's this?
This month's article continues the discussion of Java's security model begun in last month's "Under
the Hood," which provided a general overview of the security mechanisms built into the Java virtual
machine (JVM). I also looked closely at one aspect of those security mechanisms: the JVM's built-in
safety features. This month's article takes a look at yet another aspect of the JVM's built-in security
mechanisms: the class loader architecture.

A sandbox refresher

Java's security model is focused on protecting end-users from hostile programs downloaded
from untrusted sources across a network. To accomplish this goal, Java provides a
customizable "sandbox" in which Java programs run. A Java program can do anything within
the boundaries of its sandbox, but it can't take any action outside those boundaries. The
sandbox for untrusted Java applets, for example, prohibits many activities, including:

       reading or writing to the local disk
       making a network connection to any host, except the host from which the applet came
       creating a new process
       loading a new dynamic library and directly calling a native method




By making it impossible for downloaded code to perform certain actions, Java's security
model protects users from the threat of hostile code. For more information on the sandbox
concept, see last month's "Under the Hood."

The class loader architecture

One aspect of the JVM that plays an important role in the security sandbox is the class loader
architecture. In the JVM, class loaders are responsible for importing binary data that defines
the running program's classes and interfaces. In the block diagram shown in Figure 1, a single
mysterious cube identifies itself as "the class loader," but in reality, there may be more than
one class loader inside a JVM. Thus, the class loader cube of the block diagram actually
represents a subsystem that may involve many class loaders. The JVM has a flexible class
loader architecture that allows a Java application to load classes in custom ways.
                          Figure 1. Java's class loader architecture

A Java application can use two types of class loaders: a "primordial" class loader and class
loader objects. The primordial class loader (there is only one of them) is a part of the JVM
implementation. For example, if a JVM is implemented as a C program on top of an existing
operating system, then the primordial class loader will be part of that C program. The
primordial class loader loads trusted classes, including the classes of the Java API, usually
from the local disk.

At run time, a Java application can install class loader objects that load classes in custom
ways, such as by downloading class files across a network. The JVM considers any class it
loads through the primordial class loader to be trusted, regardless of whether or not the class
is part of the Java API. It views with suspicion, however, those classes it loads through class
loader objects. By default, it considers them to be untrusted. While the primordial class
loader is an intrinsic part of the virtual machine implementation, class loader objects are not.
Instead, class loader objects are written in Java, compiled into class files, loaded into the
virtual machine, and instantiated just like any other object. They really are just another part of
the executable code of a running Java application. You can see a graphical depiction of this
architecture in Figure 2.


Implementing a Class Loader
Part of the security implications of a class loader depend upon its internal implementation.
When you implement a class loader, you have two basic choices: you can extend the
ClassLoader class, or you can extend the SecureClassLoader class. The second choice is
preferred, but it is not an option for Java 1.1. If you're programming in 1.2, you may choose
to use the URL class loader rather than implementing your own, but the information in this
section will help you understand the security features of the URL class loader. In this
section, then, we'll look at how to implement both default and secure class loaders.

3.4.1. Implementing the ClassLoader Class

Aside from the primordial class loader, all Java class loaders must extend the
ClassLoaderclass (java.lang.ClassLoader). Since the ClassLoader class is abstract, it
is necessary to subclass it to create a class loader.

3.4.1.1. Protected methods in the ClassLoader class

In order to implement a class loader, we start with this method:

protected abstract Class loadClass(String name, boolean resolve)

protected Class loadClass(String name, boolean resolve)

       Using the rules of the class loader, find the class with the given name and, if indicated
       by the resolve variable, ensure that the class is resolved. If the class is not found,
       this method should throw a ClassNotFoundException. This method is abstract in
        1.1, but not in 1.2. In 1.2, you typically do not override this method.

The loadClass() method is passed a fully qualified class name (e.g., java.lang.String or
com.xyz.XYZPayrollApplet), and it is expected to return a class object that represents the
target class. If the class is not a system class, the loadClass() method is responsible for
loading the bytes that define the class (e.g., from the network).

There are five final methods (listed below) in the ClassLoader class that a class loader can
use to help it achieve its task.

protected final Class defineClass(String name, byte data[], int offset, int length)

protected final Class defineClass(String name, byte data[], int offset, int length, ProtectionDomain
pd)

        Create a Class object from an array of bytecodes. The defineClass() method runs
        the data through the bytecode verifier and then creates the Class object. This method
        also ensures that the name in the class file is the same as the name of the argument--
        that is, that the bytes actually define the desired class. We'll look at protection
        domains in Chapter 5, "The Access Controller"; if you use the signature without one,
        a default (system) domain will be provided for the class.

protected final Class findSystemClass(String name)

        Attempt to find the named class by using the internal class loader to search the user's
        CLASSPATH. If the system class is not found, a ClassNotFoundException is
        generated. In 1.2, this method searches only the classes in the Java API.

protected final Class findLoadedClass(String name)

        Find the class object for a class previously loaded by this class loader. If the class is
        not found, a null reference is returned.

Finding Previously Loaded Classes

According to the Java specification, a class loader is required to cache the classes that it has
previously loaded, so that when it is asked to load a particular class, it is not supposed to re-
read the class file. Not only is this more efficient, it allows a simpler internal implementation
of many methods, including the resolveClass() method.

The Java specification hedges this somewhat by stating that this requirement may change in
the future, when the classes will be cached by the virtual machine itself. Hence, the
ClassLoader class in JDK 1.0 did not do any caching, and it was up to concrete
implementations of class loaders to perform this caching.

Beginning with JDK 1.1, however, caching within the class loader was considered important
enough that the base ClassLoader class now performs this caching automatically: a class is
put into the cache of the class loader in the defineClass() method and may be retrieved
from the cache with the findLoadedClass() method. Since these methods are final, and
since the cache itself is a private instance variable of the ClassLoader class, this permits a
class loader to be written without any knowledge of whether the class loader or the virtual
machine is doing the caching.

protected final void resolveClass(Class c)

        For a given class, resolve all the immediately needed class references for the class;
        this will result in recursively calling the class loader to ask it to load the referenced
        class.

The loadClass() method is responsible for implementing the eight steps of the class
definition list given above. Typically, implementation of this method looks like this:

Class Definition
protected Class loadClass(String name, boolean resolve) {
        Class c;
        SecurityManager sm = System.getSecurityManager();

          // Step 1 -- Check for a previously loaded class
          c = findLoadedClass(name);
          if (c != null)
                  return c;

          // Step 2 -- Check to make sure that we can access this class
          if (sm != null) {
                  int i = name.lastIndexOf('.');
                  if (i >= 0)
                          sm.checkPackageAccess(name.substring(0, i));
          }

          // Step 3 -- Check for system class first
          try {
                  // In 1.2 only, defer to another class loader if available
                  if (parent != null)
                          c = parent.loadClass(name, resolve);
                  else

                    // Call this method in both 1.1 and 1.2
                            c = findSystemClass(name);

                  if (c != null)
                          return c;
          } catch (ClassNotFoundException cnfe) {
              // Not a system class, simply continue
          }

          // Step 4 -- Check to make sure that we can define this class
          if (sm != null) {
                  int i = name.lastIndexOf('.');
                  if (i >= 0)
                          sm.checkPackageDefinition(name.substring(0, i));
          }

          // Step 5 -- Read in the class file
          byte data[] = lookupData(name);
          // Step 6 and 7 -- Define the class from the data; this also
          //              passes the data through the bytecode verifier
          c = defineClass(name, data, 0, data.length);

          // Step 8 -- Resolve the internal references of the class
          if (resolve)
                  resolveClass(c);

          return c;
}

For most of the class loaders we're interested in, this skeleton of a class loader is sufficient,
and all we need to change is the definition of the lookupData() method (as well as the
constructor of the class, which might need various initialization parameters).

This method might be used to implement a 1.1-based class loader, where the loadClass()
method is abstract. In 1.2, however, it is easier to use the existing loadClass() method and
override only the existing findClass() method:

protected Class findClass(String name)

       Load the given class according to the internal rules of the class loader. This method
       should assume that it is responsible for implementing only steps 5, 6, and 7 in our
       list: that is, it should read the data and call the defineClass() method, but it needn't
       look for an existing implementation of the class or check to see if it is a system class.
       If the class cannot be found, this method should return null (which is what the default
       implementation of this method returns in all cases).

We'll use this method in our example of a secure class loader. If you must implement a 1.1-
based class loader, you can use the code from that example to implement a lookupData()
method that could be used by the above implementation of the loadClass() method.

From a security point of view, the loadClass() method is important because it codifies
several aspects of how Java handles security. One example of this is that the order in which
the loadClass() method looks for classes is significant. Much of the security within Java
itself depends on classes in the Java API doing the correct thing--e.g., the
java.lang.String class is final and holds the array of characters representing the string
in a private instance variable; this allows strings to be considered constants, which is
important to several aspects of Java security. When a class loader is asked to find the
java.lang.String class, it is very important that it return the class from the Java API
rather than returning a class (possibly having different and insecure semantics) it loaded
from a different location.

Hence, it is important that the class loader call the findSystemClass() method immediately
after it attempts (and fails) to find the class in its internal cache (via the findLoadedClass()
method). By codifying this behavior in the loadClass() method, the ClassLoader class
ensures that the class loader will have the correct behavior to enforce the overall security of
the virtual machine. This is why the loadClass() method is no longer abstract in 1.2. This
method really should be made final now, but that would break compatibility with
previously written class loaders.
Secure Class Loaders and the defineClass() Method

When a class is defined by a secure class loader, one of the parameters that it must specify is
a CodeSource object or a ProtectionDomain object. A Code-Source object encapsulates
certain information about the class--where it was loaded from and whether or not it was
signed (and if so, by whom); a ProtectionDomain object encapsulates information about
the specific permissions that have been granted to the class.

We're deferring discussion of these classes until Chapter 5, "The Access Controller", when
we can discuss them in their proper context.

Violating security by returning the incorrect class would have required the cooperation of
the class loader. This might have happened accidentally, if the author of the class loader did
not provide a correct implementation. It might also have happened maliciously, if the author
of the class loader intentionally wrote an incorrect implementation. The new implementation
solves the first problem, but not the second: the author of the class loader can still override
the loadClass() method directly to do whatever he wants. In general, you have to trust the
author of your class loader anyway, so the new implementation enhances security mostly by
assisting developers in writing more robust programs.

3.4.2. Implementing the SecureClassLoader Class

Starting with JDK 1.2, there is an extension of the ClassLoader class that any Java
developer can use as the superclass of her own class loader: the SecureClassLoader class
(java.security.SecureClassLoader).

In terms of security, the benefit of the SecureClassLoader class comes because it is fully
integrated with the notion of protection domains that was introduced in 1.2. We'll discuss
this integration more fully in Chapter 5, "The Access Controller", when we have an
understanding of what a protection domain is.

3.4.2.1. Protected methods of the SecureClassLoader class

The SecureClassLoader class provides this new method:

protected final Class defineClass(String name, byte[] buf, int offset, int length,

CodeSource cs)

        Define a class that is associated with the given code source. If the code source is null,
        this method is the equivalent of the defineClass() method in the base
        ClassLoader class. We'll defer showing an example of this method to Chapter 5,
        "The Access Controller", when we discuss code source objects.

As our first example of a class loader, we'll use the same paradigm for loading classes that a
Java-enabled browser uses, namely an HTTP connection to a web server:

Class Definition
public class JavaRunnerLoader extends SecureClassLoader {
        protected URL urlBase;
        public boolean printLoadMessages = true;

       public JavaRunnerLoader(String base, ClassLoader parent) {
               super(parent);
               try {
                       if (!(base.endsWith("/")))
                               base = base + "/";
                       urlBase = new URL(base);
               } catch (Exception e) {
                       throw new IllegalArgumentException(base);
               }
       }

       byte[] getClassBytes(InputStream is) {
               ByteArrayOutputStream baos = new ByteArrayOutputStream();
               BufferedInputStream bis = new BufferedInputStream(is);
               boolean eof = false;
               while (!eof) {
                       try {
                               int i = bis.read();
                               if (i == -1)
                                       eof = true;
                               else baos.write(i);
                       } catch (IOException e) {
                               return null;
                       }
               }
               return baos.toByteArray();
       }

       protected Class findClass(String name) {
               String urlName = name.replace('.', '/');
               byte buf[];
               Class cl;

               SecurityManager sm = System.getSecurityManager();
               if (sm != null) {
                       int i = name.lastIndexOf('.');
                       if (i >= 0)
                               sm.checkPackageDefinition(name.substring(0,
i));
               }
               try {
                       URL url = new URL(urlBase, urlName + ".class");
                       if (printLoadMessages)
                               System.out.println("Loading " + url);
                       InputStream is =
url.openConnection().getInputStream();
                       buf = getClassBytes(is);
                       cl = defineClass(name, buf, 0, buf.length, null);
                       return cl;
               } catch (Exception e) {
                       System.out.println("Can't load " + name + ": " +
e);
                       return null;
               }
        }
}
The key decision in using this class loader is where the classes are located--that is, the URL
that needs to be passed to the constructor. If we were using this class loader in a browser,
that URL would be the applet's CODEBASE; for an application, this location is up to the
application to decide, using whatever means it deems appropriate (in the JavaRunner
application, we used a command-line argument for that purpose). Note that the URL that is
passed to the constructor must be a directory; in order to compose that directory into a URL
later in the findClass() method, the name must end with a slash.

The logic of the findClass() method itself is simple: we need to convert the class name
(e.g., com.XYZ.HRApplet) to a URL, which we can do by replacing the package-separating
periods with slashes. Once the URL has been created, we simply obtain an input stream to
the URL, read the bytes from that stream, and pass the bytes to the defineClass() method.

Note that the findClass() method encompasses most of the logic that is necessary for the
lookupData() method we'd need if we were writing a 1.1-based class loader. The only
difference for a 1.1-based class loader is that we would not need to call the defineClass()
method, as that is called in our 1.1-based implementation of the loadClass() method.

The implementation we've just shown is the basis for the implementation of the
URLClassLoader class. The basic difference between the two is that our implementation
operates on a single URL, while the URLClassLoader class operates on an array of URLs.
The URLClassLoader class can also read JAR files while our present implementation can
only read individual class files; we'll remedy both those situations in the next section.

3.4.3. Implementing Security Policies in the Class Loader

When we discussed the algorithm used to load classes, we mentioned that you could test to
see if the class loader was allowed to access or define the package that the class belonged to.
You might, for example, want to test whether the program should be allowed to access
classes in the sun package, or define classes in the java package.

It is up to the author of the class loader to put these checks into the class loader--even in 1.2.
In 1.2, if you want to make the check for package access, you can do that by calling the
checkPackageAccess() method of the security manager in the same way that we called the
checkPackageDefinition() method, but that will only prevent you from accessing classes
that aren't found by the system class loader. Alternately in 1.2, you can use the
newInstance() method of the URLClassLoader class, which makes such a check; or you
can override the loadClass() method itself to provide such a check, as we showed earlier.
In 1.1, of course, you have to write the loadClass() method from scratch, so you can call
the security manager or not, as you deem appropriate.

In the case of defining a class in a package, the necessary code in a 1.2-based class loader
must be inserted into the findClass() method as we did in our example class loader. Note
that class loaders that are created by calling the constructor of the URLClassLoader class do
not make such a call; they allow you to define a class in any package whatsoever.

For the Launcher (and any applications built on the URLClassLoader class), then, the
default security model does not perform either of these checks. This is unfortunate: if a
program is allowed to define a class in the java package, then that class will have access to
all the package-protected classes and variables within that package, which carries with it
some risk. The reason this model is the default has to do with the way in which the access
controller defines permissions; we'll explore it more in depth when we write our own
security manager in Chapter 6, "Implementing Security Policies".




3.3. Loading Classes                                           3.5. Extensions to the Class
                                                                                    Loader




Copyright © 2001 O'Reilly & Associates. All rights reserved.


6.3 The Byte Code Verification Process
What about the concept of a "hostile compiler"? Although the Java compiler ensures that
Java source code doesn't violate the safety rules, when an application such as the HotJava
Browser imports a code fragment from anywhere, it doesn't actually know if code fragments
follow Java language rules for safety: the code may not have been produced by a known-to-
be trustworthy Java compiler. In such a case, how is the Java run-time system on your
machine to trust the incoming bytecode stream? The answer is simple: the Java run-time
system doesn't trust the incoming code, but subjects it to bytecode verification.

The tests range from simple verification that the format of a code fragment is correct, to
passing each code fragment through a simple theorem prover to establish that it plays by the
rules:

                it doesn't forge pointers,
                it doesn't violate access restrictions,
                it accesses objects as what they are (for example, InputStream objects are
                 always used as InputStreams and never as anything else).

A language that is safe, plus run-time verification of generated code, establishes a base set of
guarantees that interfaces cannot be violated.



6.3.1 The Byte Code Verifier

The bytecode verifier traverses the bytecodes, constructs the type state information, and
verifies the types of the parameters to all the bytecode instructions.
The illustration shows the flow of data and control from Java language source code through
the Java compiler, to the class loader and bytecode verifier and hence on to the Java virtual
machine, which contains the interpreter and runtime system. The important issue is that the
Java class loader and the bytecode verifier make no assumptions about the primary source of
the bytecode stream--the code may have come from the local system, or it may have
travelled halfway around the planet. The bytecode verifier acts as a sort of gatekeeper: it
ensures that code passed to the Java interpreter is in a fit state to be executed and can run
without fear of breaking the Java interpreter. Imported code is not allowed to execute by any
means until after it has passed the verifier's tests. Once the verifier is done, a number of
important properties are known:

              There are no operand stack overflows or underflows
              The types of the parameters of all bytecode instructions are known to always
               be correct
              Object field accesses are known to be legal--private, public, or protected

While all this checking appears excruciatingly detailed, by the time the bytecode verifier has
done its work, the Java interpreter can proceed, knowing that the code will run securely.
Knowing these properties makes the Java interpreter much faster, because it doesn't have to
check anything. There are no operand type checks and no stack overflow checks. The
interpreter can thus function at full speed without compromising reliability.



Security Managers and Permissions:-
Security Managers and Permissions
Once a class has been loaded into the virtual machine and checked by the verifier, the
second security mechanism of the Java platform springs into action: the security manager.
The security manager is a class that controls whether a specific operation is permitted.
Operations checked by the security manager include the following:

      Creating a new class loader
      Exiting the virtual machine
      Accessing a field of another class by using reflection
      Accessing a file
      Opening a socket connection
      Starting a print job
      Accessing the system clipboard
      Accessing the AWT event queue
      Bringing up a top-level window

There are many other checks such as these throughout the Java library.

The default behavior when running Java applications is that no security manager is installed,
so all these operations are permitted. The applet viewer, on the other hand, enforces a
security policy that is quite restrictive.

For example, applets are not allowed to exit the virtual machine. If they try calling the exit
method, then a security exception is thrown. Here is what happens in detail. The exit
method of the Runtime class calls the checkExit method of the security manager. Here is
the entire code of the exit method:

public void exit(int status)
{
  SecurityManager security = System.getSecurityManager();
  if (security != null)
      security.checkExit(status);
  exitInternal(status);
}

The security manager now checks if the exit request came from the browser or an individual
applet. If the security manager agrees with the exit request, then the checkExit method
simply returns and normal processing continues. However, if the security manager doesn't
want to grant the request, the checkExit method throws a SecurityException.

The exit method continues only if no exception occurred. It then calls the private native
exitInternal method that actually terminates the virtual machine. There is no other way of
terminating the virtual machine, and because the exitInternal method is private, it cannot
be called from any other class. Thus, any code that attempts to exit the virtual machine must
go through the exit method and thus through the checkExit security check without
triggering a security exception.

Clearly, the integrity of the security policy depends on careful coding. The providers of
system services in the standard library must always consult the security manager before
attempting any sensitive operation.

The security manager of the Java platform allows both programmers and system
administrators fine-grained control over individual security permissions. We describe these
features in the following section. First, we summarize the Java 2 platform security model.
We then show how you can control permissions with policy files. Finally, we explain how
you can define your own permission types.

NOTE

It is possible to implement and install your own security manager, but you should not
attempt this unless you are an expert in computer security. It is much safer to configure the
standard security manager.

Java Platform Security

JDK 1.0 had a very simple security model: Local classes had full permissions, and remote
classes were confined to the sandbox. Just like a child that can only play in a sandbox,
remote code was only allowed to paint on the screen and interact with the user. The applet
security manager denied all access to local resources. JDK 1.1 implemented a slight
modification: Remote code that was signed by a trusted entity was granted the same
permissions as local classes. However, both versions of the JDK provided an all-or-nothing
approach. Programs either had full access or they had to play in the sandbox.

Starting with Java SE 1.2, the Java platform has a much more flexible mechanism. A
security policy maps code sources to permission sets (see Figure 9-6).




Figure 9-6 A security policy

A code source is specified by a code base and a set of certificates. The code base specifies
the origin of the code. For example, the code base of remote applet code is the HTTP URL
from which the applet is loaded. The code base of code in a JAR file is a file URL. A
certificate, if present, is an assurance by some party that the code has not been tampered
with. We cover certificates later in this chapter.

A permission is any property that is checked by a security manager. The Java platform
supports a number of permission classes, each of which encapsulates the details of a
particular permission. For example, the following instance of the FilePermission class
states that it is okay to read and write any file in the /tmp directory.

FilePermission p = new FilePermission("/tmp/*", "read,write");

More important, the default implementation of the Policy class reads permissions from a
permission file. Inside a permission file, the same read permission is expressed as
permission java.io.FilePermission "/tmp/*", "read,write";

We discuss permission files in the next section.

Figure 9-7 shows the hierarchy of the permission classes that were supplied with Java SE
1.2. Many more permission classes have been added in subsequent Java releases.




Figure 9-7 A part of the hierarchy of permission classes

In the preceding section, you saw that the SecurityManager class has security check
methods such as checkExit. These methods exist only for the convenience of the
programmer and for backward compatibility. They all map into standard permission checks.
For example, here is the source code for the checkExit method:

public void checkExit()
{
   checkPermission(new RuntimePermission("exitVM"));
}

Each class has a protection domain, an object that encapsulates both the code source and the
collection of permissions of the class. When the SecurityManager needs to check a
permission, it looks at the classes of all methods currently on the call stack. It then gets the
protection domains of all classes and asks each protection domain if its permission collection
allows the operation that is currently being checked. If all domains agree, then the check
passes. Otherwise, a SecurityException is thrown.

Why do all methods on the call stack need to allow a particular operation? Let us work
through an example. Suppose the init method of an applet wants to open a file. It might call

Reader in = new FileReader(name);

The FileReader constructor calls the FileInputStream constructor, which calls the
checkRead method of the security manager, which finally calls checkPermission with a
FilePermission(name, "read" object. Table 9-1 shows the call stack.

Table 9-1. Call Stack During Permission Checking
Class               Method              Code Source         Permissions
SecurityManager checkPermission null                        AllPermission
SecurityManager checkRead       null                        AllPermission
FileInputStream constructor     null                        AllPermission
FileReader          constructor         null                AllPermission
applet              init                applet code source applet permissions
...
The FileInputStream and SecurityManager classes are system classes for which
CodeSource is null and permissions consist of an instance of the AllPermission class,
which allows all operations. Clearly, their permissions alone can't determine the outcome of
the check. As you can see, the checkPermission method must take into account the
restricted permissions of the applet class. By checking the entire call stack, the security
mechanism ensures that one class can never ask another class to carry out a sensitive
operation on its behalf.

NOTE

This brief discussion of permission checking explains the basic concepts. However, we omit
a number of technical details here. With security, the devil lies in the details, and we
encourage you to read the book by Li Gong for more information. For a more critical view
of the Java platform security model, see the book Securing Java: Getting Down to Business
with Mobile Code, 2nd ed., by Gary McGraw and Ed W. Felten (Wiley 1999). You can find
an online version of that book at http://www.securingjava.com.


    java.lang.SecurityManager       1.0

      void checkPermission(Permission p)          1.2

       checks whether this security manager grants the given permission. The method
       throws a SecurityException if the permission is not granted.


    java.lang.Class    1.0

      ProtectionDomain getProtectionDomain()            1.2

       gets the protection domain for this class, or null if this class was loaded without a
       protection domain.


    java.security.ProtectionDomain        1.2

      ProtectionDomain(CodeSource source, PermissionCollection
       permissions)

       constructs a protection domain with the given code source and permissions.

      CodeSource getCodeSource()

       gets the code source of this protection domain.

      boolean implies(Permission p)

       returns true if the given permission is allowed by this protection domain.
    java.security.CodeSource        1.2

      Certificate[] getCertificates()

       gets the certificate chain for class file signatures associated with this code source.

      URL getLocation()

       gets the code base of class files associated with this code source.

Security Policy Files

The policy manager reads policy files that contain instructions for mapping code sources to
permissions. Here is a typical policy file:

grant codeBase "http://www.horstmann.com/classes"
{
   permission java.io.FilePermission "/tmp/*", "read,write";
};

This file grants permission to read and write files in the /tmp directory to all code that was
downloaded from http://www.horstmann.com/classes.

You can install policy files in standard locations. By default, there are two locations:

      The file java.policy in the Java platform home directory
      The file .java.policy (notice the period at the beginning of the file name) in the user
       home directory

NOTE

You can change the locations of these files in the java.security configuration file in the
jre/lib/security. The defaults are specified as

policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy

A system administrator can modify the java.security file and specify policy URLs that
reside on another server and that cannot be edited by users. There can be any number of
policy URLs (with consecutive numbers) in the policy file. The permissions of all files are
combined.

If you want to store policies outside the file system, you can implement a subclass of the
Policy class that gathers the permissions. Then change the line

policy.provider=sun.security.provider.PolicyFile

in the java.security configuration file.

During testing, we don't like to constantly modify the standard policy files. Therefore, we
prefer to explicitly name the policy file that is required for each application. Place the
permissions into a separate file, say, MyApp.policy. To apply the policy, you have two
choices. You can set a system property inside your applications' main method:

System.setProperty("java.security.policy", "MyApp.policy");

Alternatively, you can start the virtual machine as

java -Djava.security.policy=MyApp.policy MyApp

For applets, you instead use

appletviewer -J-Djava.security.policy=MyApplet.policy MyApplet.html

(You can use the -J option of the appletviewer to pass any command-line argument to the
virtual machine.)

In these examples, the MyApp.policy file is added to the other policies in effect. If you add
a second equal sign, such as

java -Djava.security.policy==MyApp.policy MyApp

then your application uses only the specified policy file, and the standard policy files are
ignored.

CAUTION

An easy mistake during testing is to accidentally leave a .java.policy file that grants a lot
of permissions, perhaps even AllPermission, in the current directory. If you find that your
application doesn't seem to pay attention to the restrictions in your policy file, check for a
left-behind .java.policy file in your current directory. If you use a UNIX system, this is a
particularly easy mistake to make because files with names that start with a period are not
displayed by default.

As you saw previously, Java applications by default do not install a security manager.
Therefore, you won't see the effect of policy files until you install one. You can, of course,
add a line

System.setSecurityManager(new SecurityManager());

into your main method. Or you can add the command-line option -
Djava.security.manager when starting the virtual machine.

java -Djava.security.manager -Djava.security.policy=MyApp.policy MyApp

In the remainder of this section, we show you in detail how to describe permissions in the
policy file. We describe the entire policy file format, except for code certificates, which we
cover later in this chapter.
A policy file contains a sequence of grant entries. Each entry has the following form:

grant codesource
{
   permission1;
   permission2;
   . . .
};

The code source contains a code base (which can be omitted if the entry applies to code from
all sources) and the names of trusted principals and certificate signers (which can be omitted
if signatures are not required for this entry).

The code base is specified as

codeBase "url"

If the URL ends in a /, then it refers to a directory. Otherwise, it is taken to be the name of a
JAR file. For example,

grant codeBase "www.horstmann.com/classes/" { . . . };
grant codeBase "www.horstmann.com/classes/MyApp.jar" { . . . };

The code base is a URL and should always contain forward slashes as file separators, even
for file URLs in Windows. For example,

grant codeBase "file:C:/myapps/classes/" { . . . };

NOTE

Everyone knows that http URLs start with two slashes (http://). But there seems
sufficient confusion about file URLs that the policy file reader accepts two forms of file
URLs, namely, file://localFile and file:localFile. Furthermore, a slash before a
Windows drive letter is optional. That is, all of the following are acceptable:

file:C:/dir/filename.ext
file:/C:/dir/filename.ext
file://C:/dir/filename.ext
file:///C:/dir/filename.ext

Actually, in our tests, the file:////C:/dir/filename.ext is acceptable as well, and we
have no explanation for that.

The permissions have the following structure:

permission className targetName, actionList;

The class name is the fully qualified class name of the permission class (such as
java.io.FilePermission). The target name is a permission-specific value, for example, a
file or directory name for the file permission, or a host and port for a socket permission. The
actionList is also permission specific. It is a list of actions, such as read or connect,
separated by commas. Some permission classes don't need target names and action lists.
Table 9-2 lists the commonly used permission classes and their actions.

Table 9-2. Permissions and Their Associated Targets and Actions
Permission                               Target                              Action
java.io.FilePermission                   file target (see text)              read,
                                                                             write,
                                                                             execut
                                                                             e,
                                                                             delete
java.net.SocketPermission                socket target (see text)            accept,
                                                                             connec
                                                                             t,
                                                                             listen,
                                                                             resolv
                                                                             e
java.util.PropertyPermission             property target (see text)          read,
                                                                             write
java.lang.RuntimePermission              createClassLoader                   (none)
                                         getClassLoader
                                         setContextClassLoader
                                         enableContextClassLoaderOverride
                                         createSecurityManager
                                         setSecurityManager
                                         exitVM
                                         getenv.variableName
                                         shutdownHooks
                                         setFactory
                                         setIO
                                         modifyThread
                                         stopThread
                                         modifyThreadGroup
                                         getProtectionDomain
                                         readFileDescriptor
                                         writeFileDescriptor
                                         loadLibrary.libraryName
                                         accessClassInPackage.packageName
                                         defineClassInPackage.packageName
                                         accessDeclaredMembers.className
                                         queuePrintJob
                                         getStackTrace
                                         setDefaultUncaughtExceptionHandle
                                         r
                                         preferences
                                         usePolicy
java.awt.AWTPermission                   showWindowWithoutWarningBanner      (none)
                                         accessClipboard
                                         accessEventQueue
                                         createRobot
                                         fullScreenExclusive
                                         listenToAllAWTEvents
                                         readDisplayPixels
                                         replaceKeyboardFocusManager
                                         watchMousePointer
                                         setWindowAlwaysOnTop
                                         setAppletStub
java.net.NetPermission                   setDefaultAuthenticator             (none)
                                 specifyStreamHandler
                                 requestPasswordAuthentication
                                 setProxySelector
                                 getProxySelector
                                 setCookieHandler
                                 getCookieHandler
                                 setResponseCache
                                 getResponseCache
java.lang.reflect.ReflectPermiss suppressAccessChecks                             (none)
ion
java.io.SerializablePermission   enableSubclassImplementation                     (none)
                                 enableSubstitution
java.security.SecurityPermission createAccessControlContext                       (none)
                                 getDomainCombiner
                                 getPolicy
                                 setPolicy
                                 getProperty.keyName
                                 setProperty.keyName
                                 insertProvider.providerName
                                 removeProvider.providerName
                                 setSystemScope
                                 setIdentityPublicKey
                                 setIdentityInfo
                                 addIdentityCertificate
                                 removeIdentityCertificate
                                 printIdentity
                                 clearProviderProperties.providerN
                                 ame
                                 putProviderProperty.providerName
                                 removeProviderProperty.providerNa
                                 me
                                 getSignerPrivateKey
                                 setSignerKeyPair
java.security.AllPermission      (none)                                           (none)
javax.audio.AudioPermission      play                                             (none)
                                 record
javax.security.auth.AuthPermissi doAs                                             (none)
on                               doAsPrivileged
                                 getSubject
                                 getSubjectFromDomainCombiner
                                 setReadOnly
                                 modifyPrincipals
                                 modifyPublicCredentials
                                 modifyPrivateCredentials
                                 refreshCredential
                                 destroyCredential
                                 createLoginContext.contextName
                                 getLoginConfiguration
                                 setLoginConfiguration
                                 refreshLoginConfiguration
java.util.logging.LoggingPermiss control                                          (none)
ion
java.sql.SQLPermission           setLog                                           (none)

As you can see from Table 9-2, most permissions simply permit a particular operation. You
can think of the operation as the target with an implied action "permit". These permission
classes all extend the BasicPermission class (see Figure 9-7 on page 774). However, the
targets for the file, socket, and property permissions are more complex, and we need to
investigate them in detail.

File permission targets can have the following form:

file          a file
directory/    a directory
directory/*   all files in the directory
*             all files in the current directory
directory/-   all files in the directory or one of its subdirectories
-             all files in the current directory or one of its subdirectories
<<ALL FILES>> all files in the file system


For example, the following permission entry gives access to all files in the directory /myapp
and any of its subdirectories.

permission java.io.FilePermission "/myapp/-", "read,write,delete";

You must use the \\ escape sequence to denote a backslash in a Windows file name.

permission java.io.FilePermission "c:\\myapp\\-", "read,write,delete";

Socket permission targets consist of a host and a port range. Host specifications have the
following form:

hostname or IPaddress         a single host
localhost or the empty string the local host
*.domainSuffix                any host whose domain ends with the given suffix
*                             all hosts

Port ranges are optional and have the form:

:n     a single port
:n-    all ports numbered n and above
:-n    all ports numbered n and below
:n1-n2 all ports in the given range


Here is an example:

permission java.net.SocketPermission "*.horstmann.com:8000-8999",
"connect";

Finally, property permission targets can have one of two forms:

property         a specific property
propertyPrefix.* all properties with the given prefix
Examples are "java.home" and "java.vm.*".

For example, the following permission entry allows a program to read all properties that start
with java.vm.

permission java.util.PropertyPermission "java.vm.*", "read";

You can use system properties in policy files. The token ${property} is replaced by the
property value. For example, ${user.home} is replaced by the home directory of the user.
Here is a typical use of this system property in a permission entry.

permission java.io.FilePermission "${user.home}", "read,write";

To create platform-independent policy files, it is a good idea to use the file.separator
property instead of explicit / or \\ separators. To make this simpler, the special notation
${/} is a shortcut for ${file.separator}. For example,

permission java.io.FilePermission "${user.home}${/}-", "read,write";

is a portable entry for granting permission to read and write in the user's home directory and
any of its subdirectories.

NOTE

The JDK comes with a rudimentary tool, called policytool, that you can use to edit policy
files (see Figure 9-8). Of course, this tool is not suitable for end users who would be
completely mystified by most of the settings. We view it as a proof of concept for an
administration tool that might be used by system administrators who prefer point-and-click
over syntax. Still, what's missing is a sensible set of categories (such as low, medium, or
high security) that is meaningful to nonexperts. As a general observation, we believe that the
Java platform certainly contains all the pieces for a fine-grained security model but that it
could benefit from some polish in delivering these pieces to end users and system
administrators.




Figure 9-8 The policy tool

Custom Permissions

In this section, you see how you can supply your own permission class that users can refer to
in their policy files.

To implement your permission class, you extend the Permission class and supply the
following methods:
      A constructor with two String parameters, for the target and the action list
      String getActions()
      boolean equals()
      int hashCode()
      boolean implies(Permission other)

The last method is the most important. Permissions have an ordering, in which more general
permissions imply more specific ones. Consider the file permission

p1 = new FilePermission("/tmp/-", "read, write");

This permission allows reading and writing of any file in the /tmp directory and any of its
subdirectories.

This permission implies other, more specific permissions:

p2 = new FilePermission("/tmp/-", "read");
p3 = new FilePermission("/tmp/aFile", "read, write");
p4 = new FilePermission("/tmp/aDirectory/-", "write");

In other words, a file permission p1 implies another file permission p2 if

   1. The target file set of p1 contains the target file set of p2.
   2. The action set of p1 contains the action set of p2.

Consider the following example of the use of the implies method. When the
FileInputStream constructor wants to open a file for reading, it checks whether it has
permission to do so. For that check, a specific file permission object is passed to the
checkPermission method:

checkPermission(new FilePermission(fileName, "read"));

The security manager now asks all applicable permissions whether they imply this
permission. If any one of them implies it, then the check passes.

In particular, the AllPermission implies all other permissions.

If you define your own permission classes, then you need to define a suitable notion of
implication for your permission objects. Suppose, for example, that you define a
TVPermission for a set-top box powered by Java technology. A permission

new TVPermission("Tommy:2-12:1900-2200", "watch,record")

might allow Tommy to watch and record television channels 2–12 between 19:00 and 22:00.
You need to implement the implies method so that this permission implies a more specific
one, such as

new TVPermission("Tommy:4:2000-2100", "watch")

Implementation of a Permission Class
In the next sample program, we implement a new permission for monitoring the insertion of
text into a text area. The program ensures that you cannot add "bad words" such as sex,
drugs, and C++ into a text area. We use a custom permission class so that the list of bad
words can be supplied in a policy file.

The following subclass of JTextArea asks the security manager whether it is okay to add
new text:

class WordCheckTextArea extends JTextArea
{
   public void append(String text)
   {
      WordCheckPermission p = new WordCheckPermission(text, "insert");
      SecurityManager manager = System.getSecurityManager();
      if (manager != null) manager.checkPermission(p);
      super.append(text);
   }
}

If the security manager grants the WordCheckPermission, then the text is appended.
Otherwise, the checkPermission method throws an exception.

Word check permissions have two possible actions: insert (the permission to insert a
specific text) and avoid (the permission to add any text that avoids certain bad words). You
should run this program with the following policy file:

grant
{
   permission WordCheckPermission "sex,drugs,C++", "avoid";
};

This policy file grants the permission to insert any text that avoids the bad words sex, drugs,
and C++.

When designing the WordCheckPermission class, we must pay particular attention to the
implies method. Here are the rules that control whether permission p1 implies permission
p2.

      If p1 has action avoid and p2 has action insert, then the target of p2 must avoid all
       words in p1. For example, the permission

       WordCheckPermission "sex,drugs,C++", "avoid"

       implies the permission

       WordCheckPermission "Mary had a little lamb", "insert"

      If p1 and p2 both have action avoid, then the word set of p2 must contain all words
       in the word set of p1. For example, the permission

       WordCheckPermission "sex,drugs", "avoid"
       implies the permission

       WordCheckPermission "sex,drugs,C++", "avoid"

      If p1 and p2 both have action insert, then the text of p1 must contain the text of p2.
       For example, the permission

       WordCheckPermission "Mary had a little lamb", "insert"

       implies the permission

       WordCheckPermission "a little lamb", "insert"

You can find the implementation of this class in Listing 9-4.

Note that you retrieve the permission target with the confusingly named getName method of
the Permission class.

Because permissions are described by a pair of strings in policy files, permission classes
need to be prepared to parse these strings. In particular, we use the following method to
transform the comma-separated list of bad words of an avoid permission into a genuine Set.

public Set<String> badWordSet()
{
   Set<String> set = new HashSet<String>();
   set.addAll(Arrays.asList(getName().split(",")));
   return set;
}

This code allows us to use the equals and containsAll methods to compare sets. As you
saw in Chapter 2, the equals method of a set class finds two sets to be equal if they contain
the same elements in any order. For example, the sets resulting from "sex,drugs,C++" and
"C++,drugs,sex" are equal.

CAUTION

Make sure that your permission class is a public class. The policy file loader cannot load
classes with package visibility outside the boot class path, and it silently ignores any classes
that it cannot find.

The program in Listing 9-5 shows how the WordCheckPermission class works. Type any
text into the text field and click the Insert button. If the security check passes, the text is
appended to the text area. If not, an error message is displayed (see Figure 9-9).




Figure 9-9 The PermissionTest program
CAUTION

If you carefully look at Figure 9-9, you will see that the frame window has a warning border
with the misleading caption "Java Applet Window." The window caption is determined by
the showWindowWithoutWarningBanner target of the java.awt.AWTPermission. If you
like, you can edit the policy file to grant that permission.

You have now seen how to configure Java platform security. Most commonly, you will
simply tweak the standard permissions. For additional control, you can define custom
permissions that can be configured in the same way as the standard permissions.

Listing 9-4. WordCheckPermission.java

 1. import java.security.*;
 2. import java.util.*;
 3.
 4. /**
 5. * A permission that checks for bad words.
 6. * @version 1.00 1999-10-23
 7. * @author Cay Horstmann
 8. */
 9. public class WordCheckPermission extends Permission
10. {
11.     /**
12.       * Constructs a word check permission
13.       * @param target a comma separated word list
14.       * @param anAction "insert" or "avoid"
15.       */
16.     public WordCheckPermission(String target, String anAction)
17.     {
18.          super(target);
19.          action = anAction;
20.     }
21.
22.     public String getActions()
23.     {
24.          return action;
25.     }
26.
27.     public boolean equals(Object other)
28.     {
29.          if (other == null) return false;
30.          if (!getClass().equals(other.getClass())) return false;
31.          WordCheckPermission b = (WordCheckPermission) other;
32.          if (!action.equals(b.action)) return false;
33.          if (action.equals("insert")) return
getName().equals(b.getName());
34.          else if (action.equals("avoid")) return
badWordSet().equals(b.badWordSet());
35.          else return false;
36.     }
37.
38.     public int hashCode()
39.     {
40.          return getName().hashCode() + action.hashCode();
41.     }
42.
43.     public boolean implies(Permission other)
44.    {
45.         if (!(other instanceof WordCheckPermission)) return false;
46.         WordCheckPermission b = (WordCheckPermission) other;
47.         if (action.equals("insert"))
48.         {
49.            return b.action.equals("insert") &&
getName().indexOf(b.getName()) >= 0;
50.         }
51.         else if (action.equals("avoid"))
52.         {
53.            if (b.action.equals("avoid")) return
b.badWordSet().containsAll(badWordSet());
54.            else if (b.action.equals("insert"))
55.            {
56.               for (String badWord : badWordSet())
57.                  if (b.getName().indexOf(badWord) >= 0) return false;
58.               return true;
59.            }
60.            else return false;
61.         }
62.         else return false;
63.    }
64.
65.    /**
66.      * Gets the bad words that this permission rule describes.
67.      * @return a set of the bad words
68.      */
69.    public Set<String> badWordSet()
70.    {
71.         Set<String> set = new HashSet<String>();
72.         set.addAll(Arrays.asList(getName().split(",")));
73.         return set;
74.    }
75.
76.    private String action;
77. }

Listing 9-5. PermissionTest.java

 1. import java.awt.*;
 2. import java.awt.event.*;
 3. import javax.swing.*;
 4.
 5. /**
 6. * This class demonstrates the custom WordCheckPermission.
 7. * @version 1.03 2007-10-06
 8. * @author Cay Horstmann
 9. */
10. public class PermissionTest
11. {
12.     public static void main(String[] args)
13.     {
14.        System.setProperty("java.security.policy",
"PermissionTest.policy");
15.        System.setSecurityManager(new SecurityManager());
16.        EventQueue.invokeLater(new Runnable()
17.           {
18.              public void run()
19.              {
20.                 JFrame frame = new PermissionTestFrame();
21.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
22.                     frame.setVisible(true);
23.                  }
24.              });
25.     }
26. }
27.
28. /**
29. * This frame contains a text field for inserting words into a text
area that is protected
30. * from "bad words".
31. */
32. class PermissionTestFrame extends JFrame
33. {
34.     public PermissionTestFrame()
35.     {
36.          setTitle("PermissionTest");
37.          setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
38.
39.          textField = new JTextField(20);
40.          JPanel panel = new JPanel();
41.          panel.add(textField);
42.          JButton openButton = new JButton("Insert");
43.          panel.add(openButton);
44.          openButton.addActionListener(new ActionListener()
45.              {
46.                  public void actionPerformed(ActionEvent event)
47.                  {
48.                     insertWords(textField.getText());
49.                  }
50.              });
51.
52.          add(panel, BorderLayout.NORTH);
53.
54.          textArea = new WordCheckTextArea();
55.          add(new JScrollPane(textArea), BorderLayout.CENTER);
56.     }
57.
58.     /**
59.       * Tries to insert words into the text area. Displays a dialog if
the attempt fails.
60.       * @param words the words to insert
61.       */
62.     public void insertWords(String words)
63.     {
64.          try
65.          {
66.              textArea.append(words + "\n");
67.          }
68.          catch (SecurityException e)
69.          {
70.              JOptionPane.showMessageDialog(this, "I am sorry, but I cannot
do that.");
71.          }
72.     }
73.
74.     private JTextField textField;
75.     private WordCheckTextArea textArea;
76.     private static final int DEFAULT_WIDTH = 400;
77.     private static final int DEFAULT_HEIGHT = 300;
78. }
79.
80. /**
81. * A text area whose append method makes a security check to see that
no bad words are added.
82. */
83. class WordCheckTextArea extends JTextArea
84. {
85.     public void append(String text)
86.     {
87.        WordCheckPermission p = new WordCheckPermission(text, "insert");
88.        SecurityManager manager = System.getSecurityManager();
89.        if (manager != null) manager.checkPermission(p);
90.        super.append(text);
91.     }
92. }


    java.security.Permission      1.2

      Permission(String name)

       constructs a permission with the given target name.

      String getName()

       returns the target name of this permission.

      boolean implies(Permission other)

       checks whether this permission implies the other permission. That is the case if the
       other permission describes a more specific condition that is a consequence of the
       condition described by this permission.

< Back Page 3 of 7 Next >

   




Digital Signatures
Contents:

The Signature Class
Signed Classes
Implementing a Signature Class
Summary

In the previous few chapters, we've examined various aspects of Java's security package with
an eye toward the topics of this chapter: the ability to generate and to verify digital
signatures. We've now reached the fruits of that examination. In this chapter, we'll explore
the mechanisms of the digital signature.
The use and verification of digital signatures is another standard engine that is included in
the security provider architecture. Like the other engines we've examined, the classes that
implement this engine have both a public interface and an SPI for implementors of the
engine.

In the JDK, the most common use of digital signatures is to create signed classes; users have
the option of granting additional privileges to these signed classes using the mechanics of the
access controller. In addition, a security manager and a class loader can use this information
to change the policy of the security manager; this technique is quite useful in 1.1. Hence,
we'll also show an example that reads a signed JAR file.

12.1. The Signature Class
Operations on digital signatures are abstracted by the Signature class
(java.security.Signature):

public abstract class Signature extends SignatureSpi

        Provide an engine to create and verify digital signatures. In Java 1.1, there is no
        SignatureSpi class, and this class simply extends the Object class.

The Sun security provider includes a single implementation of this class that generates
signatures based on the DSA algorithm.

12.1.1. Using the Signature Class

As with all engine classes, instances of the Signature class are obtained by calling one of
these methods:

public static Signature getInstance(String algorithm)

public static Signature getInstance(String algorithm, String provider)

        Generate a signature object that implements the given algorithm. If no provider is
        specified, all providers are searched in order for the given algorithm as discussed in
        Chapter 8, "Security Providers"; otherwise, the system searches for the given
        algorithm only in the given provider. If an implementation of the given algorithm is
        not found, a NoSuchAlgorithmException is thrown. If the named security provider
        cannot be found, a NoSuchProviderException is thrown.

        Beginning in 1.2,[1] if the algorithm string is "DSA", the string "SHA/DSA" is
        substituted for it. Hence, implementors of this class that provide support for DSA
        signing must register themselves appropriately (that is, with the message digest
        algorithm name) in the security provider.

        [1]1.2 is now Java 2.

Once a signature object is obtained, the following methods can be invoked on it:
public void final initVerify(PublicKey publicKey)

        Initialize the signature object, preparing it to verify a signature. A signature object
        must be initialized before it can be used. If the key is not of the correct type for the
        algorithm or is otherwise invalid, an InvalidKeyException is thrown.

public final void initSign(PrivateKey privateKey)

        Initialize the signature object, preparing it to create a signature. A signature object
        must be initialized before it can be used. If the key is not of the correct type for the
        algorithm or is otherwise invalid, an InvalidKeyException is thrown.

public final void update(byte b)

public final void update(byte[] b)

public final void update(byte b[], int offset, int length)

        Add the given data to the accumulated data the object will eventually sign or verify.
        If the object has not been initialized, a SignatureException is thrown.

public final byte[] sign()

public final int sign(byte[] outbuf, int offset, int len)

        Create the digital signature, assuming that the object has been initialized for signing.
        If the object has not been properly initialized, a SignatureException is thrown.
        Once the signature has been generated, the object is reset so that it may generate
        another signature based on some new data (however, it is still initialized for signing;
        a new call to the initSign() method is not required).

        In the first of these methods, the signature is returned from the method. Otherwise,
        the signature is stored into the outbuf array at the given offset, and the length of the
        signature is returned. If the output buffer is too small to hold the data, an
        IllegalArgumentException will be thrown.

public final boolean verify(byte[] signature)

        Test the validity of the given signature, assuming that the object has been initialized
        for verification. If the object has not been properly initialized, then a
        SignatureException is thrown. Once the signature has been verified (whether or
        not the verification succeeds), the object is reset so that it may verify another
        signature based on some new data (no new call to the initVerify() method is
        required).

public final String getAlgorithm()

        Get the name of the algorithm this object implements.
public String toString()

        A printable version of a signature object is composed of the string "Signature
        object:" followed by the name of the algorithm implemented by the object,
        followed by the initialized state of the object. The state is either <not
        initialized>, <initialized for verifying>, or <initialized for
        signing>. However, the Sun DSA implementation of this class overrides this
        method to show the parameters of the DSA algorithm instead.

public final void setParameter(String param, Object value)

public final void setParameter(AlgorithmParameterSpec param)

        Set the parameter of the signature engine. In the first format, the named parameter is
        set to the given value; in the second format, parameters are set based on the
        information in the param specification.

        In the Sun implementation of the DSA signing algorithm, the only valid param string
        is KSEED, which requires an array of bytes that will be used to seed the random
        number generator used to generate the k value. There is no way to set this value
        through the parameter specification, which in the Sun implementation always returns
        an UnsupportedOperationException.

public final Object getParameter(String param)

        Return the named parameter from the object. The only valid string for the Sun
        implementation is KSEED.

public final Provider getProvider()

        Return the provider that supplied the implementation of this signature object.

It is no accident that this class has many similarities to the MessageDigest class; a digital
signature algorithm is typically implemented by performing a cryptographic operation on a
private key and the message digest that represents the data to be signed. For the developer,
this means that generating a digital signature is virtually the same as generating a message
digest; the only difference is that a key must be presented in order to operate on a signature
object. This difference is important, however, since it fills in the hole we noticed previously:
a message digest can be altered along with the data it represents so that the tampering is
unnoticeable. A signed message digest, on the other hand, can't be altered without
knowledge of the key that was used to create it. The use of a public key in the digital
signature algorithm makes the digital signature more attractive than a message
authentication code, in which there must be a shared key between the parties involved in the
message exchange.

Let's take our example from Chapter 9, "Message Digests" where we saved a message and
its digest to a file; we'll modify it now to save the message and the digital signature. We can
create the digital signature like this:
Class Definition
public class Send {
        public static void main(String args[]) {
                String data;
                data = "This have I thought good to deliver thee, " +
                               "that thou mightst not lose the dues of
rejoicing " +
                               "by being ignorant of what greatness is
promised thee.";

                   try {
                       FileOutputStream fos = new
FileOutputStream("test");
                       ObjectOutputStream oos = new
ObjectOutputStream(fos);
                       KeyStore ks =
                      KeyStore.getInstance(KeyStore.getDefaultType());
                       ks.load(new FileInputStream(

         System.getProperty("user.home") +

         File.separator + ".keystore"), null);
                        char c[] = new char[args[1].length()];
                        args[1].getChars(0, c.length, c, 0);
                        PrivateKey pk = (PrivateKey) ks.getKey(args[0], c);

                             Signature s = Signature.getInstance("DSA");
                             s.initSign(pk);

                           byte buf[] = data.getBytes();
                           s.update(buf);
                           oos.writeObject(data);
                           oos.writeObject(s.sign());
                   } catch (Exception e) {
                           e.printStackTrace();
                   }
         }
}

This example puts together many of the examples from the past few chapters. In order to
create the digital signature we must accomplish the following:

    1. Obtain the private key that is used to sign the data. Here we're using the conventional
       keystore database ($HOME/.keystore) and the command-line arguments to obtain the
       alias and password of the private key we want to use.
    2. Obtain a signing object via the getInstance() method and initialize it. Since we're
       creating a signature in this example, we use the initSign() method for
       initialization.
    3. Pass the data to be signed as a series of bytes to the update() method of the signing
       object. Multiple calls could be made to the update() method even though in this
       example we only need one.
    4. Obtain the signature by calling the sign() method. We save the signature bytes and
       write them to a file with the data so that the data and the signature can be retrieved at
       a later date.
Reading the data and verifying the signature are similar:

Class Definition
public class Receive {
        public static void main(String args[]) {
                try {
                       String data = null;
                       byte signature[] = null;
                       FileInputStream fis = new FileInputStream("test");
                       ObjectInputStream ois = new ObjectInputStream(fis);
                       Object o = ois.readObject();
                       try {
                           data = (String) o;
                       } catch (ClassCastException cce) {
                           System.out.println("Unexpected data in file");
                           System.exit(-1);
                       }
                       o = ois.readObject();
                       try {
                           signature = (byte []) o;
                       } catch (ClassCastException cce) {
                           System.out.println("Unexpected data in file");
                           System.exit(-1);
                       }
                       System.out.println("Received message");
                       System.out.println(data);

                             KeyStore ks =
                            KeyStore.getInstance(KeyStore.getDefaultType());
                             ks.load(new FileInputStream(

         System.getProperty("user.home") +
                                                            File.separator +
".keystore"), args[1]);

                           Certificate c = ks.getCertificate(args[0]);
                           PublicKey pk = c.getPublicKey();
                           Signature s = Signature.getInstance("DSA");
                           s.initVerify(pk);
                           s.update(data.getBytes());
                           if (s.verify(signature)) {
                                   System.out.println("Message is valid");
                           }
                           else System.out.println("Message was corrupted");
                   } catch (Exception e) {
                           System.out.println(e);
                   }
         }
}

The process of verifying the signature still requires four steps. The major differences are that
in step two, we initialize the signing object for verification by using the initVerify()
method, and in step four, we verify (rather than create) the existing signature by using the
verify() method. Note that we still have to know who signed the message in order to look
up the correct key--but more about that a little later.

12.1.2. The SignedObject Class
In our last example, we had to create an object that held both the data in which we are
interested and the signature for that data. This is a common enough requirement that Java
provides the SignedObject class (java.security.SignedObject) to encapsulate an object
and its signature:

public final class SignedObject implements Serializable

        Encapsulate an object and its digital signature. The encapsulated object must be
        serializable so that a serialization of a signed object can do a deep copy of the
        embedded object.

Signed objects are created with this constructor:

public SignedObject(Serializable o, PrivateKey pk, Signature engine)

        Create a signed object based on the given object, signing the serialized data in that
        object with the given private key and signature object. The signed object contains a
        copy of the given object; this copy is obtained by serializing the object parameter. If
        this serialization fails, an IOException is thrown.

It's very important to realize that this constructor makes, in effect, a copy of its parameter; if
you create a signed object based on a string buffer and later change the contents of the string
buffer, the data in the signed object remains unchanged. This preserves the integrity of the
object encapsulated with its signature.

Here are the methods we can use to operate on a signed object:

public Object getContent()

        Return the object embedded in the signed object. The object is reconstituted using
        object serialization; an error in serialization may cause either an IOException or a
        ClassNotFoundException to be thrown.


public byte[] getSignature()

        Return the signature embedded in the signed object.

public String getAlgorithm()

        Return the name of the algorithm that was used to sign the object.

public boolean verify(PublicKey pk, Signature s)

        Verify the signature within the embedded object with the given key and signature
        engine. The signature engine parameter may be obtained by calling the
        getInstance() method of the Signature class. The underlying signature engine
        may throw an InvalidKeyException or SignatureException.
We'll use this class in examples later in this chapter.

12.1.3. Signing and Certificates

In the previous examples, we specified on the command line the name of the entity that we
assumed generated the signature in the file. This was necessary because the file contained
only the actual signature of the entity and the data that was signed; it did not contain any
information about who the signer actually is. That's fine for an example, but it is not always
appropriate in a real application. We could have asked the user for the name of the entity that
was supposed to have signed the data, but that course is fraught with potential errors:

      The user could have no idea what names are in the keystore of the application.
       Especially in a corporate environment, users may not know what data the keystore
       database might contain.
      The user could get the name of the keystore alias wrong. Say that the application asks
       the user to enter the name of the signer; the user, knowing that the data came from
       me, may enter "sdo" as the alias of the identity.

       What the user may not remember is that when the keystore was first created, she
       received a public key from the San Diego Oil company; that public key was entered
       into the keystore with the alias "sdo." When my identity was added to the keystore, a
       different alias had to be chosen, so my public key was added with the alias
       "ScottOaks." But that was a long time ago, now forgotten, and because I use the sdo
       moniker all over my writings, the user assumes that I am the sdo in the keystore. And
       so the wrong alias will be chosen, and the signature verification will fail when it
       should have succeeded.

For these reasons, it makes more sense to include the public key with the signature and the
signed data. This allows the application to find the identity based on the unique public key in
order to determine who the signer of the data is.

We could do that by simply sending the encoded public key with the signature and data. A
better solution, however, would be to send the certificate that verifies the public key. That
way, if the public key is not found in the database, the credentials of the certificate can be
presented to the user, and the user can have the opportunity to decide on the fly if the
particular entity should be trusted.

Although an embedding of signature, data, and certificate is very common, the
SignedObject class does not include the capability to contain a certificate. So we'll use the
SignedObject class in this example, but we'll still need an object that contains the signed
object and the certificate. We'd like to do this by extending the SignedObject class, but
since that class is final we're forced to adopt this approach:

Class Definition
public class Message implements Serializable {
        SignedObject object;
        transient Certificate certificate;

          private void writeObject(ObjectOutputStream out)
         throws IOException {
                 out.defaultWriteObject();
                 try {
                         out.writeObject(certificate.getEncoded());
                 } catch (CertificateEncodingException cee) {
                         throw new IOException("Can't serialize object " +
cee);
                   }
         }

         private void readObject(ObjectInputStream in)
                                                      throws IOException,
ClassNotFoundException {
               in.defaultReadObject();
               try {
                       byte b[] = (byte []) in.readObject();
                       CertificateFactory cf =
                         CertificateFactory.getInstance("X509");
               certificate = cf.generateCertificate(new
                              ByteArrayInputStream(b));
               } catch (CertificateException ce) {
                       throw new IOException("Can't de-serialize object "
+ ce);
               }
        }
}

We've made the certificate variable in this class transient and have explicitly serialized
and deserialized it using its external encoding. As we discussed in Chapter 10, "Keys and
Certificates", whenever we have an embedded certificate or key, we must follow a procedure
like this to ensure that the receiving party is able to deserialize the class.

As it turns out, the X509 certificate implementation that comes with the JDK (that is, the
sun.security.x509.X509CertImpl class) also overrides the writeObject() and
readObject() methods, so if we serialize a certificate explicitly, the encoded data is written
to or read from the file. It is not sufficient to rely upon that, however--if we use the default
serialization methods for the Message class, a reference to the
sun.security.x509.X509CertImpl class is embedded into the serialized stream. A user
with another security provider (and hence a different implementation of the
X509Certificate class) would not be able to deserialize the stream because there is no
access to the Sun implementation of the X509Certificate class. Explicitly serializing and
deserializing the certificate as we've done here avoids embedding any reference to the
provider class and makes the data file more portable.

When we save the message to the file, we now have to make sure that we save a certificate
with it. Other than that, changes to the class are minor:

Class Definition
public class SendObject {
        public static void main(String args[]) {
                try {
                       FileOutputStream fos = new
FileOutputStream("test.obj");
                       ObjectOutputStream oos = new
ObjectOutputStream(fos);
                       KeyStore ks =
                     KeyStore.getInstance(KeyStore.getDefaultType());
                       char c[] = new char[args[1].length()];
                       args[1].getChars(0, c.length, c, 0);
                       ks.load(new FileInputStream(
                                      System.getProperty("user.home") +
                                      File.separator + ".keystore"), c);

                       Certificate certs[] =
ks.getCertificateChain(args[0]);
                       PrivateKey pk = (PrivateKey) ks.getKey(args[0], c);
                       Message m = new Message();
                       m.object = new SignedObject(
                         "This have I thought good to deliver thee, " +
                         "that thou mightst not lose the dues of rejoicing
" +
                         "by being ignorant of what greatness is promised
thee.",
                                                      pk,
Signature.getInstance("DSA"));
                       m.certificate = certs[0];
                       oos.writeObject(m);
               } catch (Exception e) {
                       System.out.println(e);
               }
        }
}

Retrieving the data is now more complicated, since we must verify both the signature in the
signed object and the identity of the authority that signed the embedded certificate:

Class Definition
public class ReceiveObject {
        private static void verifySigner(Certificate c, String name)

         throws CertificateException {
                 Certificate issuerCert = null;
                 X509Certificate sCert = null;
                 KeyStore ks = null;

                  try {
                       ks =
KeyStore.getInstance(KeyStore.getDefaultType());
                       ks.load(new FileInputStream(

         System.getProperty("user.home") +
                                              File.separator +
".keystore"), null);
               } catch (Exception e) {
                       throw new CertificateException("Invalid keystore");
               }

                  try {
                            String signer = ks.getCertificateAlias(c);
                            if (signer !=null){
                                    System.out.println("We know the signer as "
+ signer);
                                return;
                        }
                        for (Enumeration alias = ks.aliases();
                               alias.hasMoreElements();){
                                String s = (String) alias.nextElement();
                                try {
                                        sCert = (X509Certificate)
ks.getCertificate(s);
                               } catch (Exception e) {
                                       continue;
                               }
                               if
(name.equals(sCert.getSubjectDN().getName())){
                                       issuerCert = sCert;
                                       break;
                               }
                       }
               } catch(KeyStoreException kse) {
                       throw new CertificateException("Invalid keystore");
               }
               if (issuerCert == null) {
                       throw new CertificateException("No such
certificate");
               }
               try {
                       c.verify(issuerCert.getPublicKey());
               } catch (Exception e) {
                       throw new CertificateException(e.toString());
               }
        }

       private static void processCertificate(X509Certificate x509)

        throws CertificateParsingException {
                Principal p;
                p = x509.getSubjectDN();
                System.out.println("This message was signed by " +
                                                       p.getName());
                p = x509.getIssuerDN();
                System.out.println("This certificate was provided by " +
                                                       p.getName());
                try {
                        verifySigner(x509, p.getName());
                } catch (CertificateException ce) {
                        System.out.println("We don't know the certificate
signer");
                }
                try {
                        x509.checkValidity();
                } catch (CertificateExpiredException cee) {
                        System.out.println("That certificate is no longer
valid");
                } catch (CertificateNotYetValidException cnyve) {
                        System.out.println("That certificate is not yet
valid");
                }
        }

       public static void main(String args[]) {
               try {
                       FileInputStream fis = new
FileInputStream("test.obj");
                       ObjectInputStream ois = new ObjectInputStream(fis);
                       Object o = ois.readObject();
                       if (o instanceof Message) {
                               Message m = (Message) o;
                               System.out.println("Received message");
                               processCertificate((X509Certificate)
m.certificate);
                               PublicKey pk = m.certificate.getPublicKey();
                               if (m.object.verify(pk,
Signature.getInstance("DSA"))) {
                                       System.out.println("Message is
valid");

        System.out.println(m.object.getObject());
                                }
                                else System.out.println("Message signature
is invalid");
                        }
                        else System.out.println("Message is corrupted");
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
}

We've seen most of this code in previous chapters; in particular, the
processCertificate() method uses the standard certificate methods to extract and print
information about the certificate. The new code for us is primarily in the verifySigner()
method, where we search the entire keystore for a name that matches the issuer of the
certificate that was sent to us. If we find a match, we use the corresponding public key to
verify the certificate we received.

This method shows yet another need for an alternate implementation of the KeyStore class--
if you have to search the entire list of keys for a matching certificate like this, you clearly
don't want to perform a linear search each time. An alternate keystore could provide a more
efficient means of searching for certificates.




11.4. Summary                                                  12.2. Signed Classes




Copyright © 2001 O'Reilly & Associates. All rights reserved.
CODE SIGNING:-

   


Sign Java Code
Date Submitted: 2-13-2012

Several tools are required to package and sign Java code, including keytool, jar and jarsigner.
Beginning with JDK 5.0, jarsigner can generate signatures that include a time stamp,
allowing validation that the JAR file was signed while the code signing certificate was still
valid.

Approach 1 – Request a New Code Signing Certificate

   1. If necessary, download JDK from the following link:
      http://java.sun.com/javase/downloads/index.jsp
   2. Request a Code Signing Certificate from Go Daddy.
           o Create a new key store. A key store is a place where secure certificates are stored.
               This example will create a custom key store named "codesignstore" to be used only
               for a code signing certificate and the associated private key.

               keytool -genkey -alias codesigncert -keypass <yourkeypwd> -keyalg RSA -keysize
               2048 -dname "CN=displayname,O=companyname,C=US,ST=state,L=city" -keystore
               codesignstore -storepass <yourstorepwd>

           o   Create a Certificate Signing Request (CSR). A private key will be created and stored in
               the key store named "codesignstore". A CSR file named "mycsr.pem" will be created
               in the current working directory.

               keytool -certreq -v -alias codesigncert -file mycsr.pem -keystore codesignstore

           o   Purchase a code signing certificate.
           o   Click on the purchased code signing certificate credit in “My Account”. This will take
               you to the GoDaddy Secure Certificate Services Account Management web
               application. The CSR generation method must be set to manual on the request form
               for the CSR field to be visible.
           o   Submit CSR as part of the code signing request.
                     After opening the file “mycsr.pem” in an editor, copy and paste the entire
                        content of the file (including the lines containing “BEGIN NEW CERTIFICATE
                        REQUEST” and “END NEW CERTIFICATE REQUEST”) into the appropriate
                        section of the code signing request form.
           o   The company information you have supplied will be verified. The Registration
               Authority (RA) may contact you to provide additional information, if required.
           o   Once the code signing certificate has been issued, you will receive an email message
               with a link to download the certificate file and any associated intermediate
               certificates.
  3. Install the code signing certificate, in the same key store created earlier. The following
     example expects the code signing certificate file to be named “mycert.cer”. The certificate
     file is expected to be in the current working folder and in PKCS#7 format.

      keytool -import -trustcacerts -keystore codesignstore -storepass <yourstorepwd> -alias
      codesigncert -file mycert.cer

  4. Sign the JAR file using jarsigner, using the code signing certificate and the private key

      jarsigner -verbose -keystore codesignstore -storepass <yourstorepwd> -keypass
      <yourkeypwd> myapp.jar codesigncert

          o   ‘codesignstore’ is an alias to the key store where the code signing cert, the private
              key and all other certificates in the chain are contained.
          o   The unsigned input file name is “myapp.jar” and will be overwritten with the signed
              version of the file. Use the “-signedjar” command line option to specify separate
              input and output file names.
          o   ‘codesigncert’ is an alias to the private key in the key store.

      The following example adds time stamping options to the same example presented above.

      jarsigner -verbose -keystore codesignstore -storepass <yourstorepwd> -keypass
      <yourkeypwd> -tsa http://tsa.starfieldtech.com/ myapp.jar codesigncert

  5. Verify the signed JAR file

      jarsigner -verify -verbose -certs myapp.jar

  6. Distribute the code

Approach 2 – Use Existing PKCS#12 File, Containing Both Code Signing
Certificate and Private Key

  1. If necessary, download JDK from the following link:
     http://java.sun.com/javase/downloads/index.jsp
  2. Verify that the PFX/P12 file can be used with jarsigner. Execute the following command, the
     alias name required in step 5 will be displayed near the top of the output:

      keytool -list -storetype pkcs12 -keystore mycert.pfx -v

  3. Create a JAR file from Java class files, using the jar tool:

      jar cvf myapp.jar myapp.class

  4. Sign the JAR file using jarsigner, using the code signing certificate and the private key:

      jarsigner -storetype pkcs12 -keystore mycert.pfx myapp.jar "aliasname"
             o    "mycert.pfx" is the full path to the PFX/P12 file containing the code signing
                  certificate and the private key. The file should also include all intermediate
                  certificates.
             o    "aliasname" is displayed in the output of step 2, near the top. If the PFX/P12 file was
                  exported from Windows, the alias name will effectively be a GUID.
             o    When prompted, enter the password associated with the private key in the PFX/P12
                  file. You may also include the "-storepass" option to specify the password on the
                  command line.
             o    The unsigned input file name is "myapp.jar" and will be overwritten with the signed
                  version of the file. Use the "-signedjar" command line option to specify separate
                  input and output file names.

         The following example adds time stamping options to the same example presented above:

         jarsigner -storetype pkcs12 -keystore mycert.pfx -tsa http://tsa.starfieldtech.com/ myapp.jar
         "aliasname"

    5. Verify the signed JAR file

         jarsigner -verify -verbose -certs myapp.jar

    6. Distribute the code

ENCRYPTION:-


RSA encryption in Java
We introduced the notion of asymmetric encryption, in which a key needed to encrypt data is
made public, but the corresponding key needed to decrypt it is kept private, for example in a
file on the server to which clients connect. In principle, such a system solves the problem of
how to send a temporary encryption key securely to the server when opening a secure
connection*. A very common asymmetric encryption system is RSA, named after inventors
Rivest, Shamir & Adleman.
*
 If we just used a symmetric encryption system such as AES on its own, we'd have the problem of how the two
parties agree on the key in advance. This is sometimes possible, but usually, we want to transmit a temporary
key at the moment of connecting. Generally, we use an asymmetric encryption system such as RSA to transmit
the secret key, then for the rest of the conversation, use a regular symmetric encryption system using that secret
key.

Basic algorithm and terminology

RSA encryption and decryption are essentially mathematical operations. They are what are
termed exponentiation, modulo a particular number. Because of this, RSA keys actually
consist of numbers involved in this calculation, as follows:

        the public key consists of the modulus and a public exponent;
        the private key consists of that same modulus plus a private exponent.

Those interested in more details of the RSA algorithm should see this separate page.
Creating an RSA key pair in Java

As a one-off process, we need to generate an RSA key pair that from then on, we'll use for all
conversations between our clients and server.

Creating an RSA key pair essentially consists of picking a modulus, which is based on two
random primes intended to be unique to that key pair, picking a public exponent (in practice,
the common exponent 65537 is often used), then calculating the corresponding private
exponent given the modulus and public exponent. Java provides the KeyPairGenerator class
for performing this task. The essential idea is as follows:

      we create an instance of KeyPairGenerator suitable for generating RSA keys;
      we initialise the generator, telling it the bit length of the modulus that we require (see
       below);
      we call genKeyPair(), which eventually returns a KeyPair object;
      we call getPublic() and getPrivate() on the latter to pull out the public and private
       keys.

The code looks as follows:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();

Notice that we specify a key length of 2048 bits. Common values are 1024 or 2048.
Choosing an RSA key length is a tradeoff between security and performance.

We now have two Key objects. Whilst we could immediately use these to start encrypting and
decrypting, in most practical uses, we want to store these two keys for later use. For that, we
use a KeyFactory to pull out the components (modulus and exponents) of the keys.

Saving the public and private key

In practice, we need to store the public and private keys somewhere. Typically, the private
key will be placed on our server, and the public key distributed to clients. To store the key,
we simply need to pull out the modulus and the public and private exponents, then write these
numbers to some file (or put in whatever convenient place).

The Key interface allows us to pretend for a second that we don't need to worry about the
algorithm-specific details of keys. But unfortunately, in practice we do. So there also exist
"key specification" classes— RSAPublicKeySpec and RSAPrivateKeySpec in this case—
with transparent methods for pulling out the parameters that make up the key. Then, a
KeyFactory allows us to translate between Keys and their corresponding specification. It's a
bit clumsy, but the code ends up as follows:

KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(),
  RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(),
  RSAPrivateKeySpec.class);

saveToFile("public.key", pub.getModulus(),
  pub.getPublicExponent());
saveToFile("private.key", priv.getModulus(),
  priv.getPrivateExponent());

To save the moduli and exponents to file, we can just use boring old serialisation, since the
modulus and exponents are just BigInteger objects:

public void saveToFile(String fileName,
  BigInteger mod, BigInteger exp) throws IOException {
  ObjectOutputStream oout = new ObjectOutputStream(
    new BufferedOutputStream(new FileOutputStream(fileName)));
  try {
    oout.writeObject(mod);
    oout.writeObject(exp);
  } catch (Exception e) {
    throw new IOException("Unexpected error", e);
  } finally {
    oout.close();
  }
}

In our example, we end up with two files: public.key, which is distributed with out clients
(it can be packed into the jar, or whatever); meanwhile, private.key, is kept secret on our
server. Of course, we needn't even bother saving the keys to a file: they're just numbers, and
we could embed them as constant strings in our code, then pass those strings to the
constructor of BigInteger. Saving the keys to file simply makes it a bit easier to manage
keys in some cases (for example, we might change keys periodically and distribute new key
files to the clients; distributing a few bytes is often more practical than distributing the entire
code base).

Now we've got a mechanism to generate a key pair and save those keys for the future, we're
ready to consider how to actually perform RSA encryption/decryption, reading in the key
files we generated.

								
To top