The Java Persistence API(JPA): LP Java Persistence API ... · javax.persistence package. The...
Transcript of The Java Persistence API(JPA): LP Java Persistence API ... · javax.persistence package. The...
The Java Persistence API(JPA): Objective, Additional Resources, The
Java Persistence API, Object Relational Mapping Software, Entity class
Requirements, Life Cycle and Operational Characteristics of Entity:
Components
LP
Explain ORM Architecture in detail. (6 to 8)
How classes are related in JPA (Java Persistence API). (4 to 6)
The Java Persistence API(JPA)
Objective
Java Persistence API is a collection of classes and methods to persistently store the vast amounts of
data into a database. This tutorial provides you the basic understanding of Persistence (storing the
copy of database object into temporary memory), and we will learn the understanding of JAVA
Persistence API (JPA).
Any enterprise application performs database operations by storing and retrieving vast amounts of
data. Despite all the available technologies for storage management, application developers normally
struggle to perform database operations efficiently.
Generally, Java developers use lots of code, or use the proprietary framework to interact with the
database, whereas using JPA, the burden of interacting with the database reduces significantly. It
forms a bridge between object models (Java program) and relational models (database program).
Mismatches between relational and object models
Relational objects are represented in a tabular format, while object models are represented in an
interconnected graph of object format. While storing and retrieving an object model from a relational
database, some mismatch occurs due to the following reasons:
Granularity : Object model has more granularity than relational model.
Subtypes : Subtypes (means inheritance) are not supported by all types of relational
databases.
Identity : Like object model, relational model does not expose identity while writing equality.
Associations : Relational models cannot determine multiple relationships while looking into
an object domain model.
Data navigation : Data navigation between objects in an object network is different in both
models.
What is JPA?
Java Persistence API is a collection of classes and methods to persistently store the vast amounts of
data into a database which is provided by the Oracle Corporation.
Where to use JPA?
To reduce the burden of writing codes for relational object management, a programmer follows the
‘JPA Provider’ framework, which allows easy interaction with database instance. Here the required
framework is taken over by JPA.
JPA History
Earlier versions of EJB, defined persistence layer combined with business logic layer using
javax.ejb.EntityBean Interface.
While introducing EJB 3.0, the persistence layer was separated and specified as JPA 1.0 (Java
Persistence API). The specifications of this API were released along with the specifications of
JAVA EE5 on May 11, 2006 using JSR 220.
JPA 2.0 was released with the specifications of JAVA EE6 on December 10, 2009 as a part of
Java Community Process JSR 317.
JPA 2.1 was released with the specification of JAVA EE7 on April 22, 2013 using JSR 338.
JPA Providers
JPA is an open source API, therefore various enterprise vendors such as Oracle, Redhat, Eclipse, etc.
provide new products by adding the JPA persistence flavor in them. Some of these products include:
Hibernate, Eclipselink, Toplink, Spring Data JPA, etc.
Java Persistence API is a source to store business entities as relational entities. It shows how to define
a Plain Oriented Java Object (POJO) as an entity and how to manage entities with relations.
Class Level Architecture
The following image shows the class level architecture of JPA. It shows the core classes and interfaces
of JPA.
The following table describes each of the units shown in the above architecture.
Units Description
EntityManagerFactory This is a factory class of EntityManager. It creates and manages multiple
EntityManager instances.
EntityManager It is an Interface, it manages the persistence operations on objects. It works
like factory for Query instance.
Entity Entities are the persistence objects, stores as records in the database.
EntityTransaction It has one-to-one relationship with EntityManager. For each EntityManager,
operations are maintained by EntityTransaction class.
Persistence This class contain static methods to obtain EntityManagerFactory instance.
Query This interface is implemented by each JPA vendor to obtain relational objects
that meet the criteria.
The above classes and interfaces are used for storing entities into a database as a record. They help
programmers by reducing their efforts to write codes for storing data into a database so that they can
concentrate on more important activities such as writing codes for mapping the classes with database
tables.
JPA Class Relationships
In the above architecture, the relations between the classes and interfaces belong to the
javax.persistence package. The following diagram shows the relationship between them.
The relationship between EntityManagerFactory and EntityManager is one-to-many. It is a
factory class to EntityManager instances.
The relationship between EntityManager and EntityTransaction is one-to-one. For each
EntityManager operation, there is an EntityTransaction instance.
The relationship between EntityManager and Query is one-to-many. Many number of queries
can execute using one EntityManager instance.
The relationship between EntityManager and Entity is one-to-many. One EntityManager
instance can manage multiple Entities.
Most contemporary applications use relational database to store data. Recently, many vendors
switched to object database to reduce their burden on data maintenance. It means object database
or object relational technologies are taking care of storing, retrieving, updating, and maintenance.
The core part of this object relational technologies are mapping orm.xml file. As xml does not require
compilation, we can easily make changes to multiple data sources with less administration.
Object Relational Mapping
Object Relational Mapping (ORM) briefly tells you about what is ORM and how it works. ORM is a
programming ability to covert data from object type to relational type and vice versa.
The main feature of ORM is mapping or binding an object to its data in the database. While mapping
we have to consider the data, type of data and its relations with its self-entity or entity in any other
table.
Advanced Features
Idiomatic persistence : It enables you to write the persistence classes using object oriented
classes.
High Performance : It has many fetching techniques and hopeful locking techniques.
Reliable : It is highly stable and eminent. Used by many industrial programmers.
ORM Architecture
Here follow the ORM architecture.
The above architecture explains how object data is stored into relational database in three phases.
Phase1
The first phase, named as the Object data phase contains POJO classes, service interfaces and
classes. It is the main business component layer, which has business logic operations and attributes.
For example let us take an employee database as schema-
Employee POJO class contain attributes such as ID, name, salary, and designation. And
methods like setter and getter methods of those attributes.
Employee DAO/Service classes contains service methods such as create employee, find
employee, and delete employee.
Phase 2
The second phase named as mapping or persistence phase which contains JPA provider, mapping
file (ORM.xml), JPA Loader, and Object Grid.
JPA Provider : The vendor product which contains JPA flavor (javax.persistence). For example
Eclipselink, Toplink, Hibernate, etc.
Mapping file : The mapping file (ORM.xml) contains mapping configuration between the data
in a POJO class and data in a relational database.
JPA Loader : The JPA loader works like cache memory, which can load the relational grid data.
It works like a copy of database to interact with service classes for POJO data (Attributes of
POJO class).
Object Grid : The Object grid is a temporary location which can store the copy of relational
data, i.e. like a cache memory. All queries against the database is first effected on the data in
the object grid. Only after it is committed, it effects the main database.
Phase 3
The third phase is the Relational data phase. It contains the relational data which is logically connected
to the business component. As discussed above, only when the business component commit the data,
it is stored into the database physically. Until then the modified data is stored in a cache memory as
a grid format. Same is the process for obtaining data.
The mechanism of the programmatic interaction of above three phases is called as object relational
mapping.
Mapping.xml
The mapping.xml file is to instruct the JPA vendor for mapping the Entity classes with database tables.
Let us take an example of Employee entity which contains four attributes. The POJO class of Employee
entity named Employee.java is as follows:
public class Employee {
private int eid;
private String ename;
private double salary;
private String deg;
public Employee(int eid, String ename, double salary, String deg) {
super( );
this.eid = eid;
this.ename = ename;
this.salary = salary;
this.deg = deg;
}
public Employee( ) {
super();
}
public int getEid( ) {
return eid;
}
public void setEid(int eid) {
this.eid = eid;
}
public String getEname( ) {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public double getSalary( ) {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getDeg( ) {
return deg;
}
public void setDeg(String deg) {
this.deg = deg;
}
}
The above code is the Employee entity POJO class. It contain four attributes eid, ename, salary, and
deg. Consider these attributes are the table fields in the database and eid is the primary key of this
table. Now we have to design hibernate mapping file for it. The mapping file named mapping.xml is
as follows:
<? xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">
<description> XML Mapping file</description>
<entity class="Employee">
<table name="EMPLOYEETABLE"/>
<attributes>
<id name="eid">
<generated-value strategy="TABLE"/>
</id>
<basic name="ename">
<column name="EMP_NAME" length="100"/>
</basic>
<basic name="salary">
</basic>
<basic name="deg">
</basic>
</attributes>
</entity>
</entity-mappings>
The above script for mapping the entity class with database table. In this file
<entity-mappings> : tag defines the schema definition to allow entity tags into xml file.
<description> : tag defines description about application.
<entity> : tag defines the entity class which you want to convert into table in a database.
Attribute class defines the POJO entity class name.
<table> : tag defines the table name. If you want to keep class name as table name then this
tag is not necessary.
<attributes> : tag defines the attributes (fields in a table).
<id> : tag defines the primary key of the table. The <generated-value> tag defines how to
assign the primary key value such as Automatic, Manual, or taken from Sequence.
<basic> : tag is used for defining remaining attributes for table.
<column-name> : tag is used to define user defined table field name.
Annotations
Generally Xml files are used to configure specific component, or mapping two different specifications
of components. In our case, we have to maintain xml separately in a framework. That means while
writing a mapping xml file we need to compare the POJO class attributes with entity tags in
mapping.xml file.
Here is the solution: In the class definition, we can write the configuration part using annotations. The
annotations are used for classes, properties, and methods. Annotations starts with ‘@’ symbol.
Annotations are declared before the class, property or method is declared. All annotations of JPA are
defined in javax.persistence package.
Here follows the list of annotations used in our examples
Annotation Description
@Entity This annotation specifies to declare the class as entity or a table.
@Table This annotation specifies to declare table name.
@Basic This annotation specifies non constraint fields explicitly.
@Embedded This annotation specifies the properties of class or an entity whose value
instance of an embeddable class.
@Id This annotation specifies the property, use for identity (primary key of a
table) of the class.
@GeneratedValue This annotation specifies, how the identity attribute can be initialized such
as Automatic, manual, or value taken from sequence table.
@Transient This annotation specifies the property which in not persistent i.e. the value
is never stored into database.
@Column This annotation is used to specify column or attribute for persistence
property.
@SequenceGenerator This annotation is used to define the value for the property which is
specified in @GeneratedValue annotation. It creates a sequence.
@TableGenerator This annotation is used to specify the value generator for property specified
in @GeneratedValue annotation. It creates a table for value generation.
@AccessType
This type of annotation is used to set the access type. If you set
@AccessType(FIELD) then Field wise access will occur. If you set
@AccessType(PROPERTY) then Property wise assess will occur.
@JoinColumn This annotation is used to specify an entity association or entity collection.
This is used in many- to-one and one-to-many associations.
@UniqueConstraint This annotation is used to specify the field, unique constraint for primary
or secondary table.
@ColumnResult This annotation references the name of a column in the SQL query using
select clause.
@ManyToMany This annotation is used to define a many-to-many relationship between the
join Tables.
@ManyToOne This annotation is used to define a many-to-one relationship between the
join Tables.
@OneToMany This annotation is used to define a one-to-many relationship between the
join Tables.
@OneToOne This annotation is used to define a one-to-one relationship between the join
Tables.
@NamedQueries This annotation is used for specifying list of named queries.
@NamedQuery This annotation is used for specifying a Query using static name.
Java Bean Standard
Java class, encapsulates the instance values and behaviors into a single unit callled object. Java Bean
is a temporary storage and reusable component or an object. It is a serializable class which has default
constructor and getter & setter methods to initialize the instance attributes individually.
Bean Conventions
Bean contains the default constructor or a file that contains serialized instance. Therefore, a
bean can instantiate the bean.
The properties of a bean can be segregated into Boolean properties and non-Boolean
properties.
Non-Boolean property contains getter and setter methods.
Boolean property contain setter and is method.
Getter method of any property should start with small lettered ‘get’ (java method convention)
and continued with a field name that starts with capital letter. E.g. the field name is ‘salary’
therefore the getter method of this field is ‘getSalary ()’.
Setter method of any property should start with small lettered ‘set’ (java method convention),
continued with a field name that starts with capital letter and the argument value to set to
field. E.g. the field name is ‘salary’ therefore the setter method of this field is ‘setSalary (double
sal)’.
For Boolean property, is method to check if it is true or false. E.g. the Boolean property ‘empty’,
the is method of this field is ‘isEmpty ()’.
9 Service Oriented Computing: Challenges and Benefits, Service Oriented
Architecture, Web Services and J2EE, SOAP, WSDL, Web Service
Registries.
CLO5 5
What is importance of SOAP, WSDL and UDDI in webservice.
Or
Write in brief about Web Services Components.
What are service Registries and why do we use Service Registries.
Web services are open standard (XML, SOAP, HTTP etc.) based Web applications that interact with
other web applications for the purpose of exchanging data.
Web Services can convert your existing applications into Web-applications.
In this tutorial you will learn what exactly Web Services are and Why and How to use them.
To summarize, a complete web service is, therefore, any service that:
Is available over the Internet or private (intranet) networks
Uses a standardized XML messaging system
Is not tied to any one operating system or programming language
Is self-describing via a common XML grammar
Is discoverable via a simple find mechanism
Components of Web Services
The basic web services platform is XML + HTTP. All the standard web services work using the following
components
SOAP (Simple Object Access Protocol)
UDDI (Universal Description, Discovery and Integration)
WSDL (Web Services Description Language)
All these components have been discussed in the Web Services Architecture chapter.
How Does a Web Service Work?
A web service enables communication among various applications by using open standards such as
HTML, XML, WSDL, and SOAP. A web service takes the help of:
XML to tag the data
SOAP to transfer a message
WSDL to describe the availability of service.
You can build a Java-based web service on Solaris that is accessible from your Visual Basic program
that runs on Windows.
You can also use C# to build new web services on Windows that can be invoked from your web
application that is based on JavaServer Pages (JSP) and runs on Linux.
Example
Consider a simple account-management and order processing system. The accounting personnel use
a client application built with Visual Basic or JSP to create new accounts and enter new customer
orders.
The processing logic for this system is written in Java and resides on a Solaris machine, which also
interacts with a database to store information.
The steps to perform this operation are as follows:
The client program bundles the account registration information into a SOAP message.
This SOAP message is sent to the web service as the body of an HTTP POST request.
The web service unpacks the SOAP request and converts it into a command that the application
can understand.
The application processes the information as required and responds with a new unique account
number for that customer.
Next, the web service packages the response into another SOAP message, which it sends back
to the client program in response to its HTTP request.
The client program unpacks the SOAP message to obtain the results of the account registration
process.
Here are the benefits of using Web Services:
Exposing the Existing Function on the network
A web service is a unit of managed code that can be remotely invoked using HTTP, that is, it
can be activated using HTTP requests. Web services allows you to expose the functionality of
your existing code over the network. Once it is exposed on the network, other application can
use the functionality of your program.
Interoperability
Web services allow various applications to talk to each other and share data and services
among themselves. Other applications can also use the web services. For example, a VB or
.NET application can talk to Java web services and vice versa. Web services are used to make
the application platform and technology independent.
Standardized Protocol
Web services use standardized industry standard protocol for the communication. All the four
layers (Service Transport, XML Messaging, Service Description, and Service Discovery layers)
use well-defined protocols in the web services protocol stack. This standardization of protocol
stack gives the business many advantages such as a wide range of choices, reduction in the
cost due to competition, and increase in the quality.
Low Cost of Communication
Web services use SOAP over HTTP protocol, so you can use your existing low-cost internet for
implementing web services. This solution is much less costly compared to proprietary solutions
like EDI/B2B. Besides SOAP over HTTP, web services can also be implemented on other reliable
transport mechanisms like FTP.
Web services have the following special behavioral characteristics:
XML-Based
Web Services uses XML at data representation and data transportation layers. Using XML
eliminates any networking, operating system, or platform binding. Web Services based
applications are highly interoperable application at their core level.
Loosely Coupled
A consumer of a web service is not tied to that web service directly. The web service interface
can change over time without compromising the client's ability to interact with the service. A
tightly coupled system implies that the client and server logic are closely tied to one another,
implying that if one interface changes, the other must be updated. Adopting a loosely coupled
architecture tends to make software systems more manageable and allows simpler integration
between different systems.
Coarse-Grained
Object-oriented technologies such as Java expose their services through individual methods.
An individual method is too fine an operation to provide any useful capability at a corporate
level. Building a Java program from scratch requires the creation of several fine-grained
methods that are then composed into a coarse-grained service that is consumed by either a
client or another service.
Businesses and the interfaces that they expose should be coarse-grained. Web services
technology provides a natural way of defining coarse-grained services that access the right
amount of business logic.
Ability to be Synchronous or Asynchronous
Synchronicity refers to the binding of the client to the execution of the service. In synchronous
invocations, the client blocks and waits for the service to complete its operation before
continuing. Asynchronous operations allow a client to invoke a service and then execute other
functions.
Asynchronous clients retrieve their result at a later point in time, while synchronous clients
receive their result when the service has completed. Asynchronous capability is a key factor in
enabling loosely coupled systems.
Supports Remote Procedure Calls(RPCs)
Web services allow clients to invoke procedures, functions, and methods on remote objects
using an XML-based protocol. Remote procedures expose input and output parameters that a
web service must support.
Component development through Enterprise JavaBeans (EJBs) and .NET Components has
increasingly become a part of architectures and enterprise deployments over the past couple
of years. Both technologies are distributed and accessible through a variety of RPC
mechanisms.
A web service supports RPC by providing services of its own, equivalent to those of a traditional
component, or by translating incoming invocations into an invocation of an EJB or a .NET
component.
Supports Document Exchange
One of the key advantages of XML is its generic way of representing not only data, but also
complex documents. These documents can be as simple as representing a current address, or
they can be as complex as representing an entire book or Request for Quotation (RFQ). Web
services support the transparent exchange of documents to facilitate business integration.
There are two ways to view the web service architecture:
The first is to examine the individual roles of each web service actor.
The second is to examine the emerging web service protocol stack.
Web Service Roles
There are three major roles within the web service architecture:
Service Provider
This is the provider of the web service. The service provider implements the service and makes it
available on the Internet.
Service Requestor
This is any consumer of the web service. The requestor utilizes an existing web service by opening a
network connection and sending an XML request.
Service Registry
This is a logically centralized directory of services. The registry provides a central place where
developers can publish new services or find existing ones. It therefore serves as a centralized clearing
house for companies and their services.
Web Service Protocol Stack
A second option for viewing the web service architecture is to examine the emerging web service
protocol stack. The stack is still evolving, but currently has four main layers.
Service Transport
This layer is responsible for transporting messages between applications. Currently, this layer includes
Hyper Text Transport Protocol (HTTP), Simple Mail Transfer Protocol (SMTP), File Transfer Protocol
(FTP), and newer protocols such as Blocks Extensible Exchange Protocol (BEEP).
XML Messaging
This layer is responsible for encoding messages in a common XML format so that messages can be
understood at either end. Currently, this layer includes XML-RPC and SOAP.
Service Description
This layer is responsible for describing the public interface to a specific web service. Currently, service
description is handled via the Web Service Description Language (WSDL).
Service Discovery
This layer is responsible for centralizing services into a common registry and providing easy
publish/find functionality. Currently, service discovery is handled via Universal Description, Discovery,
and Integration (UDDI).
As web services evolve, additional layers may be added and additional technologies may be added to
each layer.
The next chapter explains the components of web services.
Few Words about Service Transport
The bottom of the web service protocol stack is service transport. This layer is responsible for actually
transporting XML messages between two computers.
Hyper Text Transfer Protocol (HTTP)
Currently, HTTP is the most popular option for service transport. HTTP is simple, stable, and widely
deployed. Furthermore, most firewalls allow HTTP traffic. This allows XML-RPC or SOAP messages to
masquerade as HTTP messages. This is good if you want to integrate remote applications, but it does
raise a number of security concerns.
Blocks Extensible Exchange Protocol (BEEP)
This is a promising alternative to HTTP. BEEP is a new Internet Engineering Task Force (IETF)
framework for building new protocols. BEEP is layered directly on TCP and includes a number of built-
in features, including an initial handshake protocol, authentication, security, and error handling. Using
BEEP, one can create new protocols for a variety of applications, including instant messaging, file
transfer, content syndication, and network management.
SOAP is not tied to any specific transport protocol. In fact, you can use SOAP via HTTP, SMTP, or FTP.
One promising idea is therefore to use SOAP over BEEP.
Over the past few years, three primary technologies have emerged as worldwide standards that make
up the core of today's web services technology. These technologies are discussed below.
XML-RPC
This is the simplest XML-based protocol for exchanging information between computers.
XML-RPC is a simple protocol that uses XML messages to perform RPCs.
Requests are encoded in XML and sent via HTTP POST.
XML responses are embedded in the body of the HTTP response.
XML-RPC is platform-independent.
XML-RPC allows diverse applications to communicate.
A Java client can speak XML-RPC to a Perl server.
XML-RPC is the easiest way to get started with web services.
To learn more about XML-RPC, visit our XML-RPC Tutorial .
SOAP
SOAP is an XML-based protocol for exchanging information between computers.
SOAP is a communication protocol.
SOAP is for communication between applications.
SOAP is a format for sending messages.
SOAP is designed to communicate via Internet.
SOAP is platform independent.
SOAP is language independent.
SOAP is simple and extensible.
SOAP allows you to get around firewalls.
SOAP will be developed as a W3C standard.
To learn more about SOAP, visit our SOAP Tutorial.
WSDL
WSDL is an XML-based language for describing web services and how to access them.
WSDL stands for Web Services Description Language.
WSDL was developed jointly by Microsoft and IBM.
WSDL is an XML based protocol for information exchange in decentralized and distributed
environments.
WSDL is the standard format for describing a web service.
WSDL definition describes how to access a web service and what operations it will perform.
WSDL is a language for describing how to interface with XML-based services.
WSDL is an integral part of UDDI, an XML-based worldwide business registry.
WSDL is the language that UDDI uses.
WSDL is pronounced as 'wiz-dull' and spelled out as 'W-S-D-L'.
To learn more about WSDL, visit our WSDL Tutorial.
UDDI
UDDI is an XML-based standard for describing, publishing, and finding web services.
UDDI stands for Universal Description, Discovery, and Integration.
UDDI is a specification for a distributed registry of web services.
UDDI is platform independent, open framework.
UDDI can communicate via SOAP, CORBA, and Java RMI Protocol.
UDDI uses WSDL to describe interfaces to web services.
UDDI is seen with SOAP and WSDL as one of the three foundation standards of web services.
UDDI is an open industry initiative enabling businesses to discover each other and define how
they interact over the Internet.
Service Registries and UDDI
What are Service Registries?
There are a wealth of services available on the Web. The high-profile examples are Amazon and
Google APIs, which cover services as diverse as ISBN lookups, book cover image retrieval, Web
search, spell-checking and geographical mapping, but many other services are available, performing
all sorts of task from library access to instant price quotes and reviews for shopping sites. Some
services perform a large and complex task, others perform a single task, and all speak different
‘languages’, from SOAP (Simple Object Access Protocol) to REST (Representational State Transfer).
For any given Web-based problem, there is an excellent possibility that a service is available that
offers useful functionality. Unfortunately, finding these services is not always easy, but the process
is greatly facilitated by using a service registry, designed to allow developers to register their
services and for anybody, developer or end-user, to locate useful services. A service registry is an
important part of any service-oriented architecture.
Types of Service Registry
Various service registries already exist. The first major standard to appear was UDDI (Universal
Description, Discovery and Integration), which was designed mostly with SOAP-based Web services
in mind. UDDI was originally designed with the idea that there would be very few service registries
needed – like the Yellow Pages, there would be one central source of information, which would be
available from a number of places, but each one would offer the same content. Several other types
of service registry exist, such as the JISC’s IESR (Information Environment Service Registry) project
[1], which focuses on improving resource discovery mechanisms for electronic resources, that is, to
make it easier to find materials to support teaching, learning and research. This briefing paper
focuses on UDDI, although it is important to realise that the original UDDI standard has now been
replaced by UDDI v3 [2] and is no longer generally used as part of a centralised approach. Instead,
many organisations use corporate UDDI servers that are not publicly accessible.
Why Use Service Registries?
Service registries can be accessed in a number of ways. Most can be accessed via a Web interface,
so if one is looking for a service or type of service, one can use a service registry like a typical search
engine, entering keywords and reading textual descriptions
of each service. However, many registries are designed to permit a second mode of use, where
services are described in a machine-readable way. This means that, should one service become
unavailable, the systems that were using that service can search the service registry for a second,
compatible service that could be used in its place.
Using a UDDI Service Registry
UDDI can be used in two ways, because it is both a service registry and a business registry. One
can look up businesses or organisations in the business registry, or search for services by description
or keyword – UDDI also supports a formal taxonomy system that can be used for formally classifying
services. It is sometimes more effective to begin searching for a service by looking at known
providers. When an appropriate service has been found, it can be used at once; the UDDI server
provides not only the name and description of services, but also information about where the Web
service can be found, what protocol should be used to communicate with it, and details of the
functionality that it can provide. Adding new services to a UDDI service registry may be done either
using a Web interface designed for administrative access, or through an API (application program
interface). Each different type of service registry supports its own method or methods – for example,
the IESR service registry provides a Web form through which services can be added, or an XML –
based service submission function.
Quality Issues
When adding data to any sort of service registry, it is important to ensure that the data is provided
in the form recommended by the registry. Malformed entries will not be searchable, and may confuse
other users. Equally, once you have listed a service in a service registry, remember that if the service
is moved, shut down or altered, it will also be necessary to update the listing in the registry.
Conclusion
Service registries are an important part of the service-oriented Internet, automating and
simplifying resource discovery. However, there is no single standard for service registries; as
of today, each group has its own resource discovery strategy. Taking part in a service registry will
generally lead to additional exposure for the listed services and resources, but does convey the
additional responsibility of ensuring that listings remain up-to-date.
References
1. JISC Information Environment Service Registry, <http://iesr.ac.uk/>
2. UDDI V3 Specification, Oasis,
<http://uddi.org/pubs/uddi-v3.00-published-20020719.htm>
10 Internationalization(I18N): Introduction, Setting the Locale, Isolating
Locale-Specific Data, Formatting Working with Text, Internationalization of
Network Resources, Service Providers for Internationalization
CLO3 2
Java Internationalization (i18n) is Java's built-in support for making your app able to serve users in
multiple different languages. In fact, internationalization covers more than just the language. It also
covers formatting of numbers, adjustment to date and time etc.
Internationalization is what you do to a Java application to make it able to handle different languages,
number formats etc.
Localization is what the Java application does when it adapts itself to a user with a specific language,
number format, date and time etc.
Internationalization and localization are thus two sides of the same story. Your Java application needs
to be internationalized to in order to be able to localize itself.
Internationalization is often abbreviated i18n. The 18 refers to the 18 characters between the first
letter i, and the last letter n. Localization is similarly abbreviated as L10n.
Internationalizing a Java application typically means making the application able to handle multiple
languages, number formats, date formats etc. This text gives you an overview of these aspects.
Basically, your application should be able to handle international input, output and operations. In other
words, your application should be able to adapt itself to input, output and operations specific to
different locations and user preferences.
Your application should be able to handle international input and output.
Input and output is a coarse grained categorization of what your application need to handle. Here are
the issues your application need to cover, in a bit more detail:
Handling International Input
Input is everything that your application receives from its users, either directly through the user
interface, sent to it via service calls (e.g. SOAP or REST calls), imported from files etc. Input includes:
Form input including
o Text (language + character encoding)
o Number formats
o Date and time formats and calculations
Files received
Service calls received
Handling International Output
Output is everything your application is showing or sending to its users, either during the installation
process, or during general use. Output includes:
Text (language + character encoding)
Number and currency formatting
Date and time formatting and calculations
Character comparisons
String comparisons
How many of these aspects your application needs to be able to handle depends on your application.
Keep in mind, that if users can have the application display text etc. to them in their own language,
they may also expect that support, emails sent to them, forums, help texts etc. to be in their own
language.
Adapting Operations
In addition to adapting to input and output, your application may need to adapt certain internal
operations to the users location and preferences. For instance, a web shop may need to add different
amounts of VAT to a sale, depending on what country the buyer lives in. An investment calculator
may have to take different laws and tax rates into consideration etc.
User Information Needed
In order to properly localize your application to a user you may need one or more of the following:
Preferred language
Country of residence
Current location
Preferred time zone
The user should be able to tell what language he or she prefers the application to use. Don't just
assume that a user living in a given country want the application localized to that language. For
instance, I am from Denmark but I prefer that applications are in english, so I can talk to people all
over the world about its features, without having to translate feature names etc. Let the user decide.
The country of residence of a user may impact what features are available to the user, and how these
features work. For instance, YouTube doesn't allow anyone to become a YouTube partner. Only users
living in certain countries are allowed into that program.
The current location may be interesting to know for some applications, especially for all location based
applications. The application may take action based on the users location.
Some applications, like a shared calendar, may need to know the users time zone in order to work
properly. An appointment at 10 AM - what time is that in the users country? What time is that in the
time zone that e.g. an application server is running in? Is the user temporarily out of the country and
need to show all appointments in the time zone of the temporary location?
Application Internationalization Layer
In order to handle internationalization of input and output, your application will have a kind of
internationalization layer. Here is a diagram illustrating that:
An application internationalization layer.
The internationalization layer takes care of converting between the users language and formatting,
and the language and formatting used internally in the application. For instance, String's are kept
internally in the memory of the JVM as UTF-16. The internationalization layer should convert from
whatever character encoding the input comes in (ascii, UTF-8 etc.) and to UTF-16.
The internationalization layer may not look like an abstraction layer sitting between the inner and
outer components in your application. Rather, it will most likely be a set of API calls to an
internationalization component capable of making the conversions and translations. The layer in your
application receiving the input data will call this internationalization API, and pass the converted values
on to the core operations.
In order to properly convert the input data the internationalization layer must collect the necessary
information about the user. That is, the language, character encoding, number formatting, date
formatting, time zone conversions etc. of the input data.
When the application needs to output data, the process is similar. The application decides on what to
output, and invoke the internationalization layer to have the output converted to formats suitable for
the user. That again includes both language, character encoding, number formatting, date formatting,
time zone conversions etc.
In reality, your application may look more like this:
Java internationalization components in an application.
What is going on is something like this:
1. The input (event or request) reaches an input handler (event handler / request handler) in the
application.
2. The input handler determines the user settings necessary for localization.
3. The input handler calls the I18n component to obtain localized texts, numbers, dates etc.
4. The input handler calls the application operations. If user preferences are needed to perform
the operations, they are passed to the application operations.
Your application may do internationalization a bit different from this. No worries. There are no right
and wrong designs here.
Why an Internationalization Component?
The reason you have an internationalization layer or component is to separate the internationalization
code from the rest of the application. You may choose to use Java's built-in internationalization
features, or you may use another API like ICU4J. By encapsulating your internationalization code in
an I18n component, you can change the API used inside it, without affecting the rest of your
application.
Java's Internationalization Classes
Java has a set of built-in classes that can help you handle internationalization of your application.
These classes are:
Class Description
Locale The Locale class represents a language and a country or region. A Locale may also
represent a certain type of formatting - e.g. date or number formatting.
ResourceBundle
The ResourceBundle class can contain localized texts or components (objects). You
obtain a ResourceBundle for a specific Locale, and thus obtain texts or objects
localized to that Locale.
NumberFormat The NumberFormat class is used to format numbers according to a certain Locale.
DecimalFormat The DecimalFormat class is used to format numbers according to customized
formatting patterns. These patterns are also Locale sensitive.
DateFormat The DateFormat class is used to format dates according to a specific Locale.
SimpleDateFormat The SimpleDateFormat class is used to parse and format dates according to custom
formatting patterns. These patterns are also Locale sensitive.
Each of these classes are covered in more detail in later texts in this trail.
Setting the LOCALE
The java.util.Locale class is used to represent a "geographical, political or cultural" region to localize
a given text, number, date or operation to. A Locale object may thus contain a country, region,
language, and also a variant of a language, for instance a dialect spoken in a certain region of a
country, or spoken in a different country than the country from which the language originates.
The Locale instance is handed to components that need to localize their actions, whether it is
converting the input, output, or just need it for internal operations. The Locale class cannot do any
internationalization or localization by itself.
Locale Standards
The Locale class complies with the BCP 47 (IETF BCP 47, "Tags for Identifying Languages") standard.
The Locale class also has support for the LDML (UTS#35 "Unicode Locale Data Markup Language")
standard, which is a BCP 47-compatible extension for locale data exchange. See the respective
standards for more information.
Locale Contents
A Locale instance contains the following subparts:
Language
Script
Country (region)
Variant
Extensions
Language
The language must be an ISO 639 2 or 3 character language code, or a registered language subtag
of up to 8 characters. In case a language has both a 2 and 3 character language code, use the 2
character code. A full list of language codes can be found in the IANA Language Subtag Registry.
Language codes are case insensitive, but the Locale class always use lowercase versions of the
language codes.
Script
The script code represents the written form of the language. Some languages can be written using
different scripts (e.g. different alphabets).
The script code is a 4 character code following the ISO 15924 standard. A full list of script codes can
be found in the IANA Language Subtag Registry.
Script codes are case insensitive, but the Locale class always uses a version with the first letter in
uppercase, and the rest in lowercase.
Country (Region)
The country code is a 2 character code following the ISO 3166 standard, or a UN M.49 numeric area
code. A full list of country and region codes can be found in the IANA Language Subtag Registry.
The country code is case insensitive, but the Locale class uses an uppercase version of the country
code.
Variant
The variant part describes a variant (dialect) of a language follwing the BCP 47 standard. See the
JavaDoc for the Locale class for more detail about variant.
Extensions
The extension part signals extensions to the Locale in addition to the language and region. For
instance, what calendar to use when displaying dates (Gregorian, Arab, Japanese etc.). See the
JavaDoc for the Locale class for more detail about extensions.
Creating a Locale
Creating a java.util.Locale instance can be done in four different ways:
Locale constants
Locale constructors
Locale.Builder class (from Java 7)
Locale.forLanguageTag factory method (from Java 7)
Each of these methods are covered in the sections below.
Locale Constants
The java.util.Locale class contains a set of constants that represent the most commonly used
languages in the world. These are:
Locale.CANADA
Locale.CANADA_FRENCH
Locale.CHINA
Locale.CHINESE
Locale.ENGLISH
Locale.FRANCE
Locale.FRENCH
Locale.GERMAN
Locale.GERMANY
Locale.ITALIAN
Locale.ITALY
Locale.JAPAN
Locale.JAPANESE
Locale.KOREA
Locale.KOREAN
Locale.PRC
Locale.ROOT
Locale.SIMPLIFIED_CHINESE
Locale.TAIWAN
Locale.TRADITIONAL_CHINESE
Locale.UK
Locale.US
You use one of these constants simply by referring to it, like this:
Locale locale = Locale.JAPANESE;
Locale Constructors
You can also create a java.util.Locale instance by using one of its constructors. The constructors are:
Locale(String language)
Locale(String language, String country)
Locale(String language, String country, String variant)
The language parameter should be a 2 or 3 letter ISO language code from the ISO 639 standard. You
can also use a language subtag of up to 8 characters.
The country should be a 2 character ISO country cod from the ISO 3166 standard. Alternatively a UN
M.49 character area code can be used.
The variant should be any valid BCP 47 variant of a language.
Here are a few examples:
Locale locale = new Locale("en"); // English language
Locale locale = new Locale("en", "UK"); // English language, United Kingdom
Locale locale = new Locale("en", "CA"); // English language, Canada
Locale Builder
From Java 7 you can use the Locale.Builder class to build a Locale instance. Here is an example:
Locale cLocale = new Locale.Builder().setLanguage("en")
.setRegion("US").build();
Locale.forLanguageTag()
The factory method Locale.forLanguageTag() can also be used to create a Locale instance. Here is an
example:
Locale aLocale = Locale.forLanguageTag("en-US");
Using the Locale Instance
Once you have a Locale instance you can use it as input to other components that use a Locale to
localize their functions. Here are a few examples:
Locale locale = new Locale("da", "DK");
ResourceBundle resourceBundle =
ResourceBundle.getBundle("bundleName", locale);
This example creates a Locale representing the danish language in Denmark, and uses this Locale to
obtain a ResourceBundle containing texts in danish.
The ResourceBundle class is covered in more detail in the text about the ResourceBundle class.
Locale Criticism
The idea of a Locale is to represent a certain language and a set of formatting of numbers and dates
related to that language and possibly a country or region. However, the language, number and date
formatting a user wants, may not be related to what country or region they live in.
For instance, If I am Danish but live in Spain and use a spanish netbank, that netbank may not be
able to show Danish language. So, I may choose the second best language, which for me is English.
Even if the netbank had Danish language, I may still, however, prefer English formatting of numbers,
because being a programmer, that is the number formatting I am used to. Additionally, being a
Spanish bank account, the saldo should be shown in euro. Not in GBP or DKK (Danish Kroner).
If I travel a lot I may prefer to display date and time of an application in the local time, or home time,
depending on what I am trying to do. For instance, if I need to catch a train locally, I may want local
time. But if I am phoning home to my family, I may want to be able to see what time it is where they
are.
Finally, I may want to show how a given application works to a person who doesn't speak the language
that my application is localized to (e.g. English or Danish), so I may want to temporarily change
language to e.g. Spanish or German.
All in all, it doesn't make sense to try to tie too many localization settings to the language, country or
region of a user. Let the user choose what language, time zone, what number formatting and date
formatting to use etc. Make it changeable too, and independently of each other. Do not tie it to the
home country of the user.
Formatting Working with Text
Handling Plurals
The words in a message may vary if both plural and singular word forms are possible. With the
ChoiceFormat class, you can map a number to a word or a phrase, allowing you to construct
grammatically correct messages.
In English the plural and singular forms of a word are usually different. This can present a problem
when you are constructing messages that refer to quantities. For example, if your message reports
the number of files on a disk, the following variations are possible:
There are no files on XDisk.
There is one file on XDisk.
There are 2 files on XDisk.
The fastest way to solve this problem is to create a MessageFormat pattern like this:
There are {0,number} file(s) on {1}.
Unfortunately the preceding pattern results in incorrect grammar:
There are 1 file(s) on XDisk.
You can do better than that, provided that you use the ChoiceFormat class. In this section you'll learn
how to deal with plurals in a message by stepping through a sample program called
ChoiceFormatDemo. This program also uses the MessageFormat class, which is discussed in the
previous section, Dealing with Compound Messages.
1. Define the Message Pattern
First, identify the variables in the message:
Next, replace the variables in the message with arguments, creating a pattern that can be applied to
a MessageFormat object:
There {0} on {1}.
The argument for the disk name, which is represented by{1}, is easy enough to deal with. You just
treat it like any other String variable in a MessageFormat pattern. This argument matches the element
at index 1 in the array of argument values. (See step 7.)
Dealing with argument{0} is more complex, for a couple of reasons:
The phrase that this argument replaces varies with the number of files. To construct this phrase
at run time, you need to map the number of files to a particular String. For example, the
number 1 will map to the String containing the phrase is one file. The ChoiceFormat class
allows you to perform the necessary mapping.
If the disk contains multiple files, the phrase includes an integer. The MessageFormat class lets
you insert a number into a phrase.
2. Create a ResourceBundle
Because the message text must be translated, isolate it in a ResourceBundle:
ResourceBundle bundle = ResourceBundle.getBundle(
"ChoiceBundle", currentLocale);
The sample program backs the ResourceBundle with properties files. The
ChoiceBundle_en_US.propertiescontains the following lines:
pattern = There {0} on {1}.
noFiles = are no files
oneFile = is one file
multipleFiles = are {2} files
The contents of this properties file show how the message will be constructed and formatted. The first
line contains the pattern for MessageFormat . (See step 1.) The other lines contain phrases that will
replace argument {0} in the pattern. The phrase for the multipleFiles key contains the argument {2},
which will be replaced by a number.
Here is the French version of the properties file, ChoiceBundle_fr_FR.properties
pattern = Il {0} sur {1}.
noFiles = n'y a pas de fichiers
oneFile = y a un fichier
multipleFiles = y a {2} fichiers
3. Create a Message Formatter
In this step you instantiate MessageFormat and set its Locale:
MessageFormat messageForm = new MessageFormat("");
messageForm.setLocale(currentLocale);
4. Create a Choice Formatter
The ChoiceFormat object allows you to choose, based on a double number, a particular String. The
range of double numbers, and the String objects to which they map, are specified in arrays:
double[] fileLimits = {0,1,2};
String [] fileStrings = {
bundle.getString("noFiles"),
bundle.getString("oneFile"),
bundle.getString("multipleFiles")
};
ChoiceFormat maps each element in the double array to the element in the String array that has the
same index. In the sample code the 0 maps to the String returned by calling
bundle.getString("noFiles"). By coincidence the index is the same as the value in the fileLimits array.
If the code had set fileLimits[0] to seven, ChoiceFormat would map the number 7 to fileStrings[0].
You specify the double and String arrays when instantiating ChoiceFormat:
ChoiceFormat choiceForm = new ChoiceFormat(fileLimits, fileStrings);
5. Apply the Pattern
Remember the pattern you constructed in step 1? It's time to retrieve the pattern from the
ResourceBundle and apply it to the MessageFormat object:
String pattern = bundle.getString("pattern");
messageForm.applyPattern(pattern);
6. Assign the Formats
In this step you assign to the MessageFormat object the ChoiceFormat object created in step 4:
Format[] formats = {choiceForm, null, NumberFormat.getInstance()};
messageForm.setFormats(formats);
The setFormats method assigns Format objects to the arguments in the message pattern. You must
invoke the applyPattern method before you call the setFormats method. The following table shows
how the elements of the Format array correspond to the arguments in the message pattern:
The Format Array of the ChoiceFormatDemo Program
Array Element Pattern Argument
choiceForm {0}
null {1}
NumberFormat.getInstance() {2}
7. Set the Arguments and Format the Message
At run time the program assigns the variables to the array of arguments it passes to the
MessageFormat object. The elements in the array correspond to the arguments in the pattern. For
example, messageArgument[1] maps to pattern argument {1}, which is a String containing the name
of the disk. In the previous step the program assigned a ChoiceFormat object to argument {0} of the
pattern. Therefore the number assigned to messageArgument[0] determines which String the
ChoiceFormat object selects. If messageArgument[0] is greater than or equal to 2, the String
containing the phrase are {2} files replaces argument {0} in the pattern. The number assigned to
messageArgument[2] will be substituted in place of pattern argument {2}. Here's the code that tries
this out:
Object[] messageArguments = {null, "XDisk", null};
for (int numFiles = 0; numFiles < 4; numFiles++) {
messageArguments[0] = new Integer(numFiles);
messageArguments[2] = new Integer(numFiles);
String result = messageForm.format(messageArguments);
System.out.println(result);
}
8. Run the Demo Program
Compare the messages displayed by the program with the phrases in the ResourceBundle of step 2.
Notice that the ChoiceFormat object selects the correct phrase, which the MessageFormat object uses
to construct the proper message. The output of the ChoiceFormatDemo program is as follows:
currentLocale = en_US
There are no files on XDisk.
There is one file on XDisk.
There are 2 files on XDisk.
There are 3 files on XDisk.
currentLocale = fr_FR
Il n'y a pas des fichiers sur XDisk.
Il y a un fichier sur XDisk.
Il y a 2 fichiers sur XDisk.
Il y a 3 fichiers sur XDisk.
Lesson: Internationalization of Network Resources
In a modern Internet community, many users are no longer satisfied with using only ASCII symbols
to identify a domain name or a web resource. For example, they would like to be able to register a
new domain using their native characters in Arabic or Chinese. That is why the internationalization of
network resources is a cornerstone in widening horizons for the World Wide Web.
This lesson describes the internationalization of the network Domain Name resources.
Internationalized Domain Name
Historically, an Internet domain name contained ASCII symbols only. As the Internet gained popularity
and was adopted across the world, it became necessary to support internationalization of domain
names, specifically to support domain names that include Unicode characters.
The Internationalizing Domain Names in Applications (IDNA) mechanism was adopted as the
standard to convert Unicode characters to standard ASCII domain names and thus preserve the
stability of the domain name system. This system performs a lookup service to translate user-friendly
names into network addresses.
Examples of internationalized domain names:
http://清华大学.cn
http://www.транспорт.com
If you follow these links you will see that the Unicode domain name represented in the address bar is
substituted with the ASCII string.
To implement similar functionality in your application, the java.net.IDN class provides methods to
convert domain names between ASCII and non ASCII formats.
Method Purpose
toASCII(String)
toASCII(String,
flag)
Used before sending an IDN to the domain name resolving system or writing
an IDN to a file where ASCII characters are expected, such as a DNS master
file. If the input string doesn't conform to RFC 3490, these methods throw an
IllegalArgumentException.
toUnicode(String)
toUnicode(String,
flag)
Used when displaying names to users, for example names obtained from a
DNS zone. This method translates a string from ASCII Compatible Encoding
(ACE) to Unicode code points. This method never fails; in case of an error the
input string remains the same and is returned unmodified.
The optional flag parameter specifies the behavior of the conversion process. The
ALLOW_UNASSIGNED flag allows including code points that are unassigned in Unicode 3.2. The
USE_STD3_ASCII_RULES flag ensures that the STD-3 ASCII rules are observed. You can use these
flags separately or logically OR'ed together. If neither flag is desired, use the single-parameter version
of the method.
Lesson: Service Providers for Internationalization
Service providers for internationalization enable the plug-in of locale-dependent data and services.
Because locale-dependent data and services can be plugged-in, third parties are able to provide
implementations of most locale-sensitive classes in the java.text and java.util packages.
A service is a set of programming interfaces and classes that provide access to a specific application's
functionality or feature. A service provider interface (SPI) is the set of public interfaces and abstract
classes that a service defines. A service provider implements the SPI. Service providers enable you to
create extensible applications, which you can extend without modifying its original code base. You can
enhance their functionality with new plug-ins or modules. For more information about service providers
and extensible applications, see Creating Extensible Applications.
You can use service providers for internationalization to provide custom implementations of the
following locale-sensitive classes:
BreakIterator objects
Collator objects
Language code, country code, and variant name for the Locale class
Time zone names
Currency symbols
DateFormat objects
DateFormatSymbols objects
NumberFormat objects
DecimalFormatSymbols objects
The corresponding SPIs are contained both in java.text.spi and in java.util.spi packages:
java.util.spi java.text.spi
CurrencyNameProvider
LocaleServiceProvider
TimeZoneNameProvider
BreakIteratorProvider
CollatorProvider
DateFormatProvider
DateFormatSymbolsProvider
DecimalFormatSymbolsProvider
NumberFormatProvider
For example, if you want to provide a NumberFormat object for a new locale, implement the
java.text.spi.NumberFormatProvider class and implement these methods:
getCurrencyInstance(Locale locale)
getIntegerInstance(Locale locale)
getNumberInstance(Locale locale)
getPercentInstance(Locale locale)
Locale loc = new Locale("da", "DK");
NumberFormat nf = NumberFormatProvider.getNumberInstance(loc);
These methods first check whether the Java runtime environment supports the requested locale; if
so, the methods use that support. Otherwise, the methods invoke the getAvailableLocales methods of
installed providers for the appropriate interface to find a provider that supports the requested locale.
For an in-depth example of how to use service providers for internationalization, see Installing a
Custom Resource Bundle as an Extension. This section shows you how to implement the
ResourceBundleControlProvider interface, which enables you to use any custom
ResourceBundle.Control classes without any additional changes to the source code of your application.
Installing a Custom Resource Bundle as an Extension
The section Customizing Resource Bundle Loading shows you how to change how resource bundles
are loaded. This involves deriving a new class from the class ResourceBundle.Control, then retrieving
the resource bundle by invoking the following method:
ResourceBundle getBundle(
String baseName,
Locale targetLocale,
ResourceBundle.Control control)
The parameter control is your implementation of ResourceBundle.Control.
The java.util.spi.ResourceBundleControlProvider interface enables you to change how the following
method loads resource bundles:
ResourceBundle getBundle(
String baseName,
Locale targetLocale)
Note that this version of the ResourceBundle.getBundle method does not require an instance of the
ResourceBundle.Control class. ResourceBundleControlProvider is a service provider interface (SPI).
SPIs enable you to create extensible applications, which are those that you can extend easily without
modifying their original code base. See Creating Extensible Applications for more information.
To use SPIs, you first create a service provider by implementing an SPI like
ResourceBundleControlProvider. When you implement an SPI, you specify how it will provide the
service. The service that the ResourceBundleControlProvider SPI provides is to obtain an appropriate
ResourceBundle.Control instance when your application invokes the method
ResourceBundle.getBundle(String baseName, Locale targetLocale). You package the service provider
with the Java Extension Mechanism as an installed extension. When you run your application, you do
not name your extensions in your class path; the runtime environment finds and loads these
extensions.
An installed implementation of the ResourceBundleControlProvider SPI replaces the default
ResourceBundle.Control class (which defines the default bundle loading process). Consequently, the
ResourceBundleControlProvider interface enables you to use any of the custom
ResourceBundle.Control classes without any additional changes to the source code of your application.
In addition, this interface enables you to write applications without having to refer to any of your
custom ResourceBundle.Control classes.
The RBCPTest.java sample shows how to implement the ResourceBundleControlProvider interface and
how to package it as an installed extension. This sample, which is packaged in the zip file RBCPTest.zip,
consists of the following files:
src
o java.util.spi.ResourceBundleControlProvider
o RBCPTest.java
o rbcp
PropertiesResourceBundleControl.java
PropertiesResourceBundleControlProvider.java
XMLResourceBundleControl.java
XMLResourceBundleControlProvider.java
o resources
RBControl.properties
RBControl_zh.properties
RBControl_zh_CN.properties
RBControl_zh_HK.properties
RBControl_zh_TW.properties
XmlRB.xml
XmlRB_ja.xml
lib
o rbcontrolprovider.jar
build: Contains all files packaged in rbcontrolprovider.jar as well as the class file RBCPTest.class
build.xml
The following steps show you how to re-create the contents of the file RBCPTest.zip, how the RBCPTest
sample works, and how to run it:
1. Create implementations of the ResourceBundle.Control class.
2. Implement the ResourceBundleControlProvider interface.
3. In your application, invoke the method ResourceBundle.getBundle.
4. Register the service provider by creating a configuration file.
5. Package the provider, its required classes, and the configuration file in a JAR file.
6. Run the RBCPTest program.
1. Create implementations of the ResourceBundle.Control class.
The RBCPTest.java sample uses two implementations of ResourseBundle.Control:
PropertiesResourceBundleControlProvider.java: This is the same ResourceBundle.Control
implementation that is defined in Customizing Resource Bundle Loading.
XMLResourceBundleControl.java: This ResourceBundle.Control implementation loads XML-
based bundles with the method Properties.loadFromXML.
XML Properties Files
As described in the section Backing a ResourceBundle with Properties Files, properties files are simple
text files. They contain one key-value pair on each line. XML properties files are just like properties
files: they contain key-value pairs except they have an XML structure. The following is the XML
properties file XmlRB.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties [
<!ELEMENT properties ( comment?, entry* ) >
<!ATTLIST properties version CDATA #FIXED "1.0">
<!ELEMENT comment (#PCDATA) >
<!ELEMENT entry (#PCDATA) >
<!ATTLIST entry key CDATA #REQUIRED>
]>
<properties>
<comment>Test data for RBCPTest.java</comment>
<entry key="type">XML</entry>
</properties>
The following is the properties text file equivalent:
# Test data for RBCPTest.java
type = XML
All XML properties text files have the same structure:
A DOCTYPE declaration that specifies the Document Type Definition (DTD): The DTD defines
the structure of an XML file. Note: You can use the following DOCTYPE declaration instead in
an XML properties file:
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
The system URI (http://java.sun.com/dtd/properties.dtd) is not accessed when exporting or
importing properties; it is a string that uniquely identifies the DTD of XML properties files.
Root element <properties>: This element contains all the other elements.
Any number of <comment> elements: These are used for comments.
Any number of <entry> elements: Use the attribute key to specify the key; specify the value
of the key between the <entry> tags.
See the Properties class for more information about XML properties files.
2. Implement the ResourceBundleControlProvider interface.
This interface contains one method, the ResourceBundle.Control getControl(String baseName)
method. The parameter baseName is the name of the resource bundle. In the method definition of
getBundle, specify the instance of ResourceBundle.Control that should be returned given the name of
the resource bundle.
The RBCPTest sample contains two implementations of the ResourceBundleControlProvider interface,
PropertiesResourceBundleControlProvider.java and XMLResourceBundleControlProvider.java. The
method PropertiesResourceBundleControlProvider.getBundle returns an instance of
PropertiesResourceBundleControl if the base name of the resource bundle starts with
resources.RBControl (in this example, all the resource files are contained in the package resources):
package rbcp;
import java.util.ResourceBundle;
import java.util.spi.ResourceBundleControlProvider;
public class PropertiesResourceBundleControlProvider
implements ResourceBundleControlProvider {
static final ResourceBundle.Control PROPERTIESCONTROL =
new PropertiesResourceBundleControl();
public ResourceBundle.Control getControl(String baseName) {
System.out.println("Class: " + getClass().getName() + ".getControl");
System.out.println(" called for " + baseName);
// Throws a NPE if baseName is null.
if (baseName.startsWith("resources.RBControl")) {
System.out.println(" returns " + PROPERTIESCONTROL);
return PROPERTIESCONTROL;
}
System.out.println(" returns null");
System.out.println();
return null;
}
}
Similarly, the method XMLResourceBundleControlProvider.getControl returns an instance of
XMLResourceBundleControl if the base name of the resource bundle starts with resources.Xml.
Note: You can create one implementation of the ResourceBundleControlProvider interface that returns
either an instance of PropertiesResourceBundleControl or XMLResourceBundleControl depending on
the base name.
3. In your application, invoke the method ResourceBundle.getBundle.
The class RBCPTest retrieves resource bundles with the method ResourceBundle.getBundle:
import java.io.*;
import java.net.*;
import java.util.*;
public class RBCPTest {
public static void main(String[] args) {
ResourceBundle rb = ResourceBundle.getBundle(
"resources.XmlRB", Locale.ROOT);
String type = rb.getString("type");
System.out.println("Root locale. Key, type: " + type);
System.out.println();
rb = ResourceBundle.getBundle("resources.XmlRB", Locale.JAPAN);
type = rb.getString("type");
System.out.println("Japan locale. Key, type: " + type);
System.out.println();
test(Locale.CHINA);
test(new Locale("zh", "HK"));
test(Locale.TAIWAN);
test(Locale.CANADA);
}
private static void test(Locale locale) {
ResourceBundle rb = ResourceBundle.getBundle(
"resources.RBControl", locale);
System.out.println("locale: " + locale);
System.out.println(" region: " + rb.getString("region"));
System.out.println(" language: " + rb.getString("language"));
System.out.println();
}
}
Note that no implementations of ResourceBundle.Control or ResourceBundleControlProvider appear in
this class. Because the ResourceBundleControlProvider interface uses the Java Extension Mechanism,
the runtime environment finds and loads these implementations. However,
ResourceBundleControlProvider implementations and other service providers that are installed with
the Java Extension Mechanism are loaded using the ServiceLoaderclass. Using this class means that
you have to register the service provider with a configuration file, which is described in the next step.
4. Register the service provider by creating a configuration file.
The name of the configuration file is the fully qualified name of the interface or class that the provider
implemented. The configuration file contains the fully qualified class name of your provider. The file
java.util.spi.ResourceBundleControlProvider contains the fully qualified names of
PropertiesResourceBundleControlProvider and XMLResourceBundleControlProvider, one name per
line:
rbcp.XMLResourceBundleControlProvider
rbcp.PropertiesResourceBundleControlProvider
5. Package the provider, its required classes, and the configuration file in a JAR file.
Compile the source files. From the directory that contains the file build.xml, run the following
command:
javac -d build src/java.* src/rbcp/*.java
This command will compile the source files contained in the src directory and put the class files in the
build directory. On Windows, ensure that you use the backslash (\) to separate directory and file
names.
Create a JAR file that contains the compiled class files, resource files, and the configuration file in the
following directory structure:
META-INF
o services
java.util.spi.ResourceBundleControlProvider
rbcp
o PropertiesResourceBundleControl.class
o PropertiesResourceBundleControlProvider.class
o XMLResourceBundleControl.class
o XMLResourceBundleControlProvider.class
resources
o RBControl.properties
o RBControl_zh.properties
o RBControl_zh_CN.properties
o RBControl_zh_HK.properties
o RBControl_zh_TW.properties
o XmlRB.xml
o XmlRB_ja.xml
Note that the configuration file java.util.spi.ResourceBundleControlProvider must be packaged in the
directory /META-INF/services. This sample packages these files in the JAR file rbcontrolprovider.jar in
the lib directory.
See Packaging Programs in JAR Files for more information about creating JAR files.
Alternatively, download and install Apache Ant, which is a tool that enables you to automate build
processes, such as compiling Java files and creating JAR files. Ensure that the Apache Ant executable
file is in your PATH environment variable so that you can run it from any directory. Once you have
installed Apache Ant, follow these steps:
1. Edit the file build.xml and change ${JAVAC} to the full path name of your Java compiler, javac,
and ${JAVA} to the full path name of your Java runtime executable, java.
2. Run the following command from the same directory that contains the file build.xml:
ant jar
This command compiles the Java source files and packages them, along with the required
resource and configuration files, into the JAR file rbcontrolprovider.jar in the lib directory.
6. Run the RBCPTest program.
At a command prompt, run the following command from the directory that contains the build.xml file:
java -Djava.ext.dirs=lib -cp build RBCPTest
This command assumes the following:
The JAR file that contains the compiled code of the RBCPTest sample is in the directory lib.
The compiled class, RBCPTest.class, is in the build directory.
Alternatively, use Apache Ant and run the following command from the directory that contains the
build.xml file:
ant run
When you install a Java extension, you typically put the JAR file of the extension in the lib/ext directory
of your JRE. However, this command specifies the directory that contains Java extensions with the
system property java.ext.dirs.
The RBCPTest program first attempts to retrieve resource bundles with the base name
resources.XmlRB and the locales Locale.ROOT and Local.JAPAN. The output of the program retrieving
these resource bundles is similar to the following:
Class: rbcp.XMLResourceBundleControlProvider.getControl
called for resources.XmlRB
returns rbcp.XMLResourceBundleControl@16c1857
Root locale. Key, type: XML
Class: rbcp.XMLResourceBundleControlProvider.getControl
called for resources.XmlRB
returns rbcp.XMLResourceBundleControl@16c1857
Japan locale. Key, type: Value from Japan locale
The program successfully obtains an instance of XMLResourceBundleControl and accesses the
properties files XmlRB.xml and XmlRB_ja.xml.
When the RBCPTest program tries to retrieve a resource bundle, it calls all the classes defined in the
configuration file java.util.spi.ResourceBundleControlProvider. For example, when the program
retrieves the resource bundle with the base name resources.RBControl and the locale Locale.CHINA,
it prints the following output:
Class: rbcp.XMLResourceBundleControlProvider.getControl
called for resources.RBControl
returns null
Class: rbcp.PropertiesResourceBundleControlProvider.getControl
called for resources.RBControl
returns rbcp.PropertiesResourceBundleControl@1ad2911
locale: zh_CN
region: China
language: Simplified Chinese
J2EE Frameworks and Design Patterns
Why do we need Design Patterns?
List different J2EE Design patterns and explain any two of them.
J2EE DESIGN PATTERNS
First we shall start with what are design pattern?
We can say a design pattern is simply a description of a recurring solution to a problem, given a
context. The context is the environment, surroundings, situation, or interrelated conditions within
which the problem exists.
Second why do need to use design patterns?
Design patterns have a number of advantages like -
1. Once described, any level engineer can use the pattern.
2. They allow for reuse without having to reinvent in every a project.
3. They allow to better define system structure.
4. They provide a design vocabulary.
5. They provide reusable artifacts.
6. Patterns can form frameworks that can then be used for implementations.
http://www.corej2eepatterns.com/index.htm
There are a number of patterns that have been identified by the Sun Java Center for the
presentation tier. We have tried to explain them in this section , we are starting with a small
explanation and then a complete section on each patterns.
Intercepting Filter : Facilitates preprocessing and post-processing of a request.
Front Controller : Provides a centralized controller for managing the handling of requests.
Composite View : Creates an aggregate View from atomic subcomponents.
View Helper : Encapsulates logic that is not related to presentation formatting into Helper
components.
Dispatcher View : Combines a Dispatcher component with the Front Controller and View Helper
patterns, deferring many activities to View processing.
Service to Worker :Combines a Dispatcher component with the Front
Controller and View Helper patterns.
Business Delegate :Reduces coupling between presentation-tier clients and business services. It
hides the underlying implementation details of the business service, such as lookup and access
details of the EJB architecture.
Session Facade : Encapsulate the complexity of interactions between the business objects
participating in a workflow. The Session Facade manages the business objects, and provides a
uniform coarse-grained service access layer to clients.
Service Locator : Multiple clients can reuse the Service Locator object to reduce code complexity,
provide a single point of control, and improve performance by providing a caching facility.
Transfer Object Assembler : It is used to build the required model or submodel. The Transfer
Object Assembler uses Transfer Objects to retrieve data from various business objects and other
objects that define the model or part of the model.
Value List Handler :The most critical concern in a distributed paradigm is the latency time. Value
List Handler Pattern suggests an alternate approach of using ejb-finder methods. The pattern is
used to control the search, cache the results and provide the results to the client using a
lightweight mechanism.
Composite Entity :It model, represent, and manage a set of interrelated persistent objects rather
than representing them as individual fine-grained entity beans. A Composite Entity bean
represents a graph of objects.
Transfer Object :Encapsulate the business data. A single method call is used to send and retrieve
the Transfer Object. When the client requests the enterprise bean for the business data, the
enterprise bean can construct the Transfer Object, populate it with its attribute values, and pass it
by value to the client.
Service Activator :Service Activator enables asynchronous access to enterprise beans and other
business services. It receive asynchronous client requests and messages. On receiving a message,
the Service Activator locates and invokes the necessary business methods on the business service
components to fulfill the request asynchronously. In EJB2.0, Message Driven beans can be used to
implement Service Activator for message based enterprise applications. The Service Activator is a
JMS Listener and delegation service that creates a message façade for the EJBs.
Data Access Object : Abstracts and encapsulate all access to the data source. The DAO manages
the connection with the data source to obtain and store data.
J2EE Pattern Relationships
Note: Please refer to the Pattern Relationships Diagram while reading the following text.
Intercepting Filter intercepts incoming requests and outgoing responses and applies a filter. These filters may be
added and removed in a declarative manner, allowing them to be applied unobtrusively in a variety of combinations.
After this preprocessing and/or post-processing is complete, the final filter in the group vectors control to the
original target object. For an incoming request, this is often a Front Controller, but may be a View.
Front Controller is a container to hold the common processing logic that occurs within the presentation tier and that
may otherwise be erroneously placed in a View. A controller handles requests and manages content retrieval,
security, view management, and navigation, delegating to a Dispatcher component to dispatch to a View.
Application Controller centralizes control, retrieval, and invocation of view and command processing. While a Front
Controller acts as a centralized access point and controller for incoming requests, the Application Controller is
responsible for identifying and invoking commands, and for identifying and dispatching to views.
Context Object encapsulates state in a protocol-independent way to be shared throughout your application.
Using Context Object makes testing easier, facilitating a more generic test environment with reduced dependence
upon a specific container.
View Helper encourages the separation of formatting-related code from other business logic. It suggests using
Helper components to encapsulate logic relating to initiating content retrieval, validation, and adapting and
formatting the model. The View component is then left to encapsulate the presentation formatting. Helper
components typically delegate to the business services via a Business Delegate or an Application Service, while a
View may be composed of multiple subcomponents to create its template.
Composite View suggests composing a View from numerous atomic pieces. Multiple smaller views, both static and
dynamic, are pieced together to create a single template. The Service to Worker and Dispatcher View patterns
represent a common combination of other patterns from the catalog. The two patterns share a common structure,
consisting of a controller working with a Dispatcher, Views, and Helpers. Service to Worker and Dispatcher
View have similar participant roles, but differ in the division of labor among those roles. Unlike Service to
Worker, Dispatcher View defers business processing until view processing has been performed.
Business Delegate reduces coupling between remote tiers and provides an entry point for accessing remote services
in the business tier. A Business Delegate might also cache data as necessary to improve performance. A Business
Delegate encapsulates a Session Façade and maintains a one-to-one relationship with that Session Façade.
An Application Service uses a Business Delegate to invoke a Session Façade.
Service Locator encapsulates the implementation mechanisms for looking up business service components.
A Business Delegate uses a Service Locator to connect to a Session Façade. Other clients that need to locate and
connect to Session Façade, other business-tier services, and web services can use a Service Locator.
Session Façade provides coarse-grained services to the clients by hiding the complexities of the business service
interactions. A Session Façade might invoke several Application Service implementations or Business Objects.
A Session Façade can also encapsulate a Value List Handler.
Application Service centralizes and aggregates behavior to provide a uniform service layer to the business tier
services. An Application Service might interact with other services or Business Objects. An Application Service can
invoke other Application Services and thus create a layer of services in your application.
Business Object implements your conceptual domain model using an object model. Business Objects separate
business data and logic into a separate layer in your application. Business Objects typically represent persistent
objects and can be transparently persisted using Domain Store.
Composite Entity implements a Business Object using local entity beans and POJOs. When implemented with bean-
managed persistence, a Composite Entity uses Data Access Objects to facilitate persistence.
The Transfer Object pattern provides the best techniques and strategies to exchange data across tiers (that is,
across system boundaries) to reduce the network overhead by minimizing the number of calls to get data from
another tier.
The Transfer Object Assembler constructs a composite Transfer Object from various sources. These sources could
be EJB components, Data Access Objects, or other arbitrary Java objects. This pattern is most useful when the client
needs to obtain data for the application model or part of the model.
The Value List Handler uses the GoF iterator pattern to provide query execution and processing services. The Value
List Handler caches the results of the query execution and return subsets of the result to the clients as requested.
By using this pattern, it is possible to avoid overheads associated with finding large numbers of entity beans.
The Value List Handler uses a Data Access Object to execute a query and fetch the results from a persistent store.
Data Access Object enables loose coupling between the business and resource tiers. Data Access
Object encapsulates all the data access logic to create, retrieve, delete, and update data from a persistent
store. Data Access Object uses Transfer Object to send and receive data.
Service Activator enables asynchronous processing in your enterprise applications using JMS. A Service Activator can
invoke Application Service, Session Façade or Business Objects. You can also use several Service Activators to
provide parallel asynchronous processing for long running tasks.
Domain Store provides a powerful mechanism to implement transparent persistence for your object model. It
combines and links several other patterns including Data Access Objects.
Web Service Broker exposes and brokers one or more services in your application to external clients as a web
service using XML and standard web protocols. A Web Service Broker can interact with Application
Service and Session Façade. A Web Service Broker uses one or more Service Activators to perform asynchronous
processing of a request.