JBOSS EJB WEB SERVICES Example

Employee Service.java
---------------------------------
package com.crm.services;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import com.crm.bean.Employee;
/**
* @author AnilKumar
*
*/
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface EmployeeService {
public Employee getEmployee(long pin);
}

EmployeeServiceImpl.java
-------------------------------------
package com.crm.services;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

import com.crm.bean.Employee;
import com.crm.model.EmployeeDAO;
import com.crm.modelinterface.cmsEmployee;
/**
* @author AnilKumar
*
*/
@Stateless
@WebService(endpointInterface = "com.crm.services.EmployeeService")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class EmployeeServiceImpl {

@WebMethod(operationName = "getEmployee")
public Employee getEmployee(@WebParam(name = "pin")
long pin) {
cmsEmployee employee2 = new EmployeeDAO();
// Employee employee2 = employeeDAO.getEmployeebyemployee(pin);

Employee employee = employee2.getEmployeebyemployee(pin);

System.out.println(employee.getFirstname());
return employee;
}

}

deploy above two classes by archieving in a jar and copy it to deploy folder of jboss
then run ur jboss server with url http://localhost:8080/jbossws there u will get all ur
web services running in your server

the client program will be like this

package com.crm.serviceClient;

import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;

import com.crm.bean.Employee;
import com.crm.services.EmployeeService;
/**
* @author AnilKumar
*
*/
@WebServiceClient(name = "EmployeeServiceImplService", targetNamespace = "http://services.crm.com/",
wsdlLocation = "http://localhost:8080/jarfilename/EmployeeServiceImpl?wsdl")
public class EmployeeServiceClient extends Service {
protected EmployeeServiceClient(URL wsdlDocumentLocation,
QName serviceName) {
super(wsdlDocumentLocation, serviceName);
// TODO Auto-generated constructor stub
}

public EmployeeServiceClient() throws MalformedURLException {
super(new URL(
"http://localhost:8080/jarfilename/EmployeeServiceImpl?wsdl"),
new QName("http://services.crm.com/",
"EmployeeServiceImplService"));
}

@WebEndpoint
public EmployeeService getEmployeeServiceport() {
return (EmployeeService) super.getPort(new QName(
"http://services.crm.com/", "EmployeeServiceImplPort"),
EmployeeService.class);

}

public static void main(String[] args) throws MalformedURLException {

try {
EmployeeService service = new EmployeeServiceClient().getEmployeeServiceport();

if (service != null) {
System.out.println("Serrvice not null");
Employee employee1 = service.getEmployee(18);

System.out.println(employee1.getFirstname());
System.out.println(employee1.getLastname());
}

} catch (Exception e) {
e.printStackTrace();
}

}

}

How to Improve Your Memory & Exercise Your Brain

How to Improve Your Memory & Exercise Your Brain
Everyone can take steps to improve their memory, with time and practice most people can gain the ability to memorize seemingly impossible amounts of information. Whether you want to win the World Memory Championships, ace your history test, or simply remember where you put your keys, this article can get you started. Scientists believe that exercising your brain can create a `cognitive reserve' that will help you stay sharp as you age.

1. Convince yourself that you do have a good memory that will improve. Too many people get stuck here and convince themselves that their memory is bad, that they are just not good with names, that numbers just slip out of their minds for some reason. Erase those thoughts and vow to improve your memory. Commit yourself to the task and bask in your achievements it's hard to keep motivated if you beat yourself down every time you make a little bit of progress.

2. Keep your brain active. The brain is not a muscle, but regularly "exercising" the brain actually does keep it growing and spurs the development of new nerve connections that can help improve memory. By developing new mental skills especially complex ones such as learning a new language or learning to play a new musical instrument and challenging your brain with puzzles and games you can keep your brain active and improve its physiological functioning.

3. Exercise daily. Regular aerobic exercise improves circulation and efficiency throughout the body, including in the brain, and can help ward off the memory loss that comes with aging. Exercise also makes you more alert and relaxed, and can thereby improve your memory uptake, allowing you to take better mental "pictures."

4. Reduce stress. Chronic stress, although it does not physically damage the brain, can make remembering much more difficult. Even temporary stresses can make it more difficult to effectively focus on concepts and observe things. Try to relax, regularly practice yoga or other stretching exercises, and see a doctor if you have severe chronic stress.

5. Eat well and eat right. There are a lot of herbal supplements on the market that claim to improve memory, but none have yet been shown to be effective in clinical tests (although small studies have shown some promising results for ginkgo biloba and phosphatidylserine). A healthy diet, however, contributes to a healthy brain, and foods containing antioxidants broccoli, blueberries, spinach, and berries, for example and Omega-3 fatty acids appear to promote healthy brain functioning. Feed your brain with such supplements as Thiamine, Vitamin E, Niacin and Vitamin B-6. Grazing, eating 5 or 6 small meals throughout the day instead of 3 large meals, also seems to improve mental functioning (including memory) by limiting dips in blood sugar, which may negatively affect the brain.

6. Take better pictures. Often we forget things not because our memory is bad, but rather because our observational skills need work. One common situation where this occurs (and which almost everyone can relate to) is meeting new people. Often we don't really learn people's names at first because we aren't really concentrating on remembering them. You'll find that if you make a conscious effort to remember such things, you'll do much better. One way to train yourself to be more observant is to look at an unfamiliar photograph for a few seconds and then turn the photograph over and describe or write down as many details as you can about the photograph. Try closing your eyes and picturing the photo in your mind. Use a new photograph each time you try this exercise, and with regular practice you will find you're able to remember more details with even shorter glimpses of the photos.

7. Give yourself time to form a memory. Memories are very fragile in the short-term, and distractions can make you quickly forget something as simple as a phone number. The key to avoid losing memories before you can even form them is to be able to focus on the thing to be remembered for a while without thinking about other things, so when you're trying to remember something, avoid distractions and complicated tasks for a few minutes.

8. Create vivid, memorable images. You remember information more easily if you can visualize it. If you want to associate a child with a book, try not to visualize the child reading the book that's too simple and forgettable. Instead, come up with something more jarring, something that sticks, like the book chasing the child, or the child eating the book. It's your mind make the images as shocking and emotional as possible to keep the associations strong.

9. Repeat things you need to learn. The more times you hear, see, or think about something, the more surely you'll remember it, right? It's a no-brainer. When you want to remember something, be it your new coworker's name or your best friend's birthday, repeat it, either out loud or silently. Try writing it down; think about it.

10. Group things you need to remember. Random lists of things (a shopping list, for example) can be especially difficult to remember. To make it easier, try categorizing the individual things from the list. If you can remember that, among other things, you wanted to buy four different kinds of vegetables, you'll find it easier to remember all four.

11. Organize your life. Keep items that you frequently need, such as keys and eyeglasses, in the same place every time. Use an electronic organizer or daily planner to keep track of appointments, due dates for bills, and other tasks. Keep phone numbers and addresses in an address book or enter them into your computer or cell phone. Improved organization can help free up your powers of concentration so that you can remember less routine things. Even if being organized doesn't improve your memory, you'll receive a lot of the same benefits (i.e. you won't have to search for your keys anymore).

12. Try meditation. Research now suggests that people who regularly practice "mindfulness" meditation are able to focus better and may have better memories. Mindfulness (also known as awareness or insight meditation) is the type commonly practiced in Western countries and is easy to learn. Studies at Massachusetts General Hospital show that regular meditation thickens the cerebral cortex in the brain by increasing the blood flow to that region. Some researchers believe this can enhance attention span, focus, and memory.

13. Sleep well. The amount of sleep we get affects the brain's ability to recall recently learned information. Getting a good night's sleep a minimum of seven hours a night may improve your short-term memory and long-term relational memory, according to recent studies conducted at the Harvard Medical School.
14. Build your memorization arsenal. Learn pegs, memory palaces, and the Dominic System. These techniques form the foundation for mnemonic techniques, and will visibly improve your memory.

15. Venture out and learn from your mistakes. Go ahead and take a stab at memorizing the first one hundred digits of pi, or, if you've done that already, the first one thousand. Memorize the monarchs of England through your memory palaces, or your grocery list through visualization. Through diligent effort you will eventually master the
art of memorization.

MBean Example in JBoss

A Hello World Service
package com.acme;


import org.jboss.system.ServiceMBean;

public interface HelloWorldServiceMBean extends ServiceMBean
{
// Configure getters and setters for the message attribute
String getMessage();
void setMessage(String message);

// The print message operation
void printMessage();
}



package com.acme;


import org.jboss.system.ServiceMBeanSupport;

public class HelloWorldService extends ServiceMBeanSupport implements HelloWorldServiceMBean
{
// Our message attribute
private String message = "Sorry no message today";

// Getters and Setters
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}

// The printMessage operation
public void printMessage()
{
log.info(message);
}

// The lifecycle
protected void startService() throws Exception
{
log.info("Starting with message=" + message);
}
protected void stopService() throws Exception
{
log.info("Stopping with message=" + message);
}
}

jboss-service.xml

<?xml?>

<server>
<mbean code="com.acme.HelloWorldService" name="acme.com:service=HelloWorld">
<attribute name="Message">Hello World</attribute>
</mbean>
</server>


Sar File directory structure
hello-world.sar

hello-world.sar/META-INF/jboss-service.xml
hello-world.sar/com/acme/HelloWorldService.class
hello-world.sar/com/acme/HelloWorldServiceMBean.class






open Office to pdf conversion and document processing

package com.documentProcessing;

import java.io.Serializable;

public class FindReplace implements Serializable{
String find;
String replace;


public FindReplace() {
// TODO Auto-generated constructor stub
}
public FindReplace(String bookmark, String fieldName) {
this.find = bookmark;
this.replace = fieldName;
}

public String getFind() {
return find;
}

public void setFind(String find) {
this.find = find;
}

public String getReplace() {
return replace;
}

public void setReplace(String replace) {
this.replace = replace;
}
}




package com.documentProcessing;


import java.io.Serializable;
import java.util.List;

import com.sun.star.frame.XDesktop;
import com.sun.star.text.XTextDocument;

/**
* Class created to help the document manipulation.
*
* @author Marco Silva
*
*/
public class OpenOffice implements Serializable {
// Open Office Controllers
public XDesktop xDesktop;
public XTextDocument xTextDocument;

// Process Document
public String libraryDocumentName;
public String documentName;
public List findReplaceList;

public String getDocumentName() {
return documentName;
}
public void setDocumentName(String documentName) {
this.documentName = documentName;
}

public List getFindReplaceList() {
return findReplaceList;
}
public void setFindReplaceList(List findReplaceList) {
this.findReplaceList = findReplaceList;
}

public String getLibraryDocumentName() {
return libraryDocumentName;
}
public void setLibraryDocumentName(String libraryDocumentName) {
this.libraryDocumentName = libraryDocumentName;
}

public XDesktop getXDesktop() {
return xDesktop;
}
public void setXDesktop(XDesktop desktop) {
xDesktop = desktop;
}

public XTextDocument getXTextDocument() {
return xTextDocument;
}
public void setXTextDocument(XTextDocument textDocument) {
xTextDocument = textDocument;
}

public void closeDocument() {
try {
if (xTextDocument != null) xTextDocument.dispose();
if (xDesktop != null) xDesktop.terminate();
} catch (Exception e) {}
}
}



package com.documentProcessing;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.ejb.Stateless;

import ooo.connector.BootstrapSocketConnector;

import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.text.XTextDocument;
import com.sun.star.text.XTextRange;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.XInterface;
import com.sun.star.util.XSearchDescriptor;
import com.sun.star.util.XSearchable;

public class OpenOfficeManager {
OpenOffice oofice;

/**
* Create the OpenOffice Document Controller
*
* @return OpenOffice
*/
public void openOfficeDocument(String docLibrary, String docName,
List findReplace) {
oofice = new OpenOffice();
XMultiComponentFactory xMCF = null;

try {
// TODO: Make sure the location of the open office is correct
// String sOffice = System.getProperty( "os.name" ).startsWith(
// "Windows" ) ? "C:\\Program Files\\OpenOffice.org 2.0\\program" :
// "//home//eanilkumar//openoffice//usr//lib//openoffice//program";

String sOffice = "/opt/openoffice.org2.3/program";

// Bootstrap open office with the location of the OpenOffice
// executable file
/*
* URL[] jarList = new URL[] { new URL("file://" + sOffice) };
* URLClassLoader loader = new URLClassLoader(jarList);
*/

XComponentContext xContext = BootstrapSocketConnector
.bootstrap(sOffice);

// Get the remote office service manager
xMCF = xContext.getServiceManager();
if (xMCF != null) {
Object oDesktop = xMCF.createInstanceWithContext(
"com.sun.star.frame.Desktop", xContext);
oofice.xDesktop = (XDesktop) UnoRuntime.queryInterface(
XDesktop.class, oDesktop);

} else
System.out
.println("Can't create a desktop. No connection, no remote office servicemanager available!");

// Update documents names
oofice.documentName = docName;
oofice.libraryDocumentName = docLibrary;
oofice.findReplaceList = findReplace;

openTextdocument();

} catch (Exception e) {
System.out.println("Exception in Document opening");
e.printStackTrace();
}
}

/**
*
*/
public void closeDocument() {
oofice.closeDocument();
}

/**
* Open the document library
*
* @param OpenOffice
* oofice
*/
public void openTextdocument() {
try {

XComponent xComponent = openDocument(oofice.xDesktop,
oofice.libraryDocumentName + oofice.documentName);
oofice.xTextDocument = (XTextDocument) UnoRuntime.queryInterface(
XTextDocument.class, xComponent);
} catch (Exception e) {
e.printStackTrace(System.err);
}
}

/**
* @param XDesktop
* xDesktop - Open Office Desktop, used to open the document
* @param sURL -
* location of the document
*
* @return XComponent - the component - internal open office document
* controller
*/
protected XComponent openDocument(XDesktop xDesktop, String sURL) {
XComponent xComponent = null;
XComponentLoader xComponentLoader = null;

// Open the document in hidden mode, will not display the document
PropertyValue xArgs[] = new PropertyValue[1];
xArgs[0] = new PropertyValue();
xArgs[0].Name = "Hidden";
xArgs[0].Value = new Boolean(true);

try {
xComponentLoader = (XComponentLoader) UnoRuntime.queryInterface(
XComponentLoader.class, xDesktop);

// xComponent =
// xComponentLoader.loadComponentFromURL("private:factory/scalc",
// "_blank", 0, xArgs);
xComponent = xComponentLoader.loadComponentFromURL(sURL, "_blank",
0, xArgs);

// xComponent = xComponentLoader.loadComponentFromURL("", "_blank",
// 0, xArgs);
} catch (Exception e) {
e.printStackTrace();
}
return xComponent;
}

/**
* Save the document as PDF
*
* @param OpenOffice
* oofice
*/
public void savePDFDocument() {
PropertyValue xValues[] = new PropertyValue[2];
xValues[0] = new PropertyValue();
xValues[0].Name = "CompressMode";
xValues[0].Value = "0";
xValues[1] = new PropertyValue();
xValues[1].Name = "FilterName";
xValues[1].Value = "writer_pdf_Export";
XStorable xStorable = (XStorable) UnoRuntime.queryInterface(
XStorable.class, oofice.xTextDocument);
try {

System.out.println("Pdf Dpcument to save path"
+ oofice.libraryDocumentName + oofice.documentName);
xStorable.storeToURL(oofice.libraryDocumentName + "tmp//"
+ oofice.documentName + ".pdf", xValues);
} catch (Exception e) {
e.printStackTrace();
}
}

public String GetDocumentText() {
return oofice.xTextDocument.getText().getString();
}

/**
* Find all specific string in the document and replace for another string.
* Used in merge database information in the document
*
* @param OpenOffice
* oofice
*/
public void replaceDocument(Map record) {

if (oofice.findReplaceList == null)
return;

Iterator ite = oofice.findReplaceList.iterator();

while (ite.hasNext()) {

// Map findReplace = (Map) ite.next();

FindReplace findReplace = (FindReplace) ite.next();

// String value = (String) record.get((String)
// findReplace.get("library_field_field"));
// String bookmark = (String)
// findReplace.get("library_field_bookmark");

String value = (String) record.get((String) findReplace
.getReplace());

String bookmark = (String) findReplace.getFind();

if ((value != null) && (bookmark != null))
replaceDocumentText(oofice.xTextDocument, bookmark, value);
}
}

/**
* @param XTextDocument
* xTextDocument - Open Office Document
* @param String
* find - string to find in the document
* @param String
* replace - string to replace
*/
protected void replaceDocumentText(XTextDocument xTextDocument,
String find, String replace) {
XInterface xSearchInterface = null;
XTextRange xSearchTextRange = null;

try {
do {
// the findfirst returns a XInterface
xSearchInterface = (XInterface) FindFirst(xTextDocument, find);

if (xSearchInterface != null) {
// get the TextRange form the XInterface
xSearchTextRange = (XTextRange) UnoRuntime.queryInterface(
XTextRange.class, xSearchInterface);
xSearchTextRange.setString(replace);
}
} while (xSearchInterface != null);

} catch (Exception e) {
e.printStackTrace();
}
}

/**
* @param XTextDocument
* xTextDocument - Open Office Document
* @param sSearchString -
* string to search
*
* @return XInterface - position where the string are
*/
protected XInterface FindFirst(XTextDocument xTextDocument,
String sSearchString) {
XSearchDescriptor xSearchDescriptor = null;
XSearchable xSearchable = null;
XInterface xSearchInterface = null;

try {
xSearchable = (XSearchable) UnoRuntime.queryInterface(
XSearchable.class, xTextDocument);
xSearchDescriptor = (XSearchDescriptor) xSearchable
.createSearchDescriptor();
xSearchDescriptor.setSearchString(sSearchString);

XPropertySet xPropertySet = null;
xPropertySet = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, xSearchDescriptor);
xPropertySet.setPropertyValue("SearchRegularExpression",
new Boolean(true));

xSearchInterface = (XInterface) xSearchable
.findFirst(xSearchDescriptor);
} catch (Exception e) {
e.printStackTrace();
}
return xSearchInterface;
}

public static void main(String[] args) {

}

public void processDocument(String filePath, String fileName,
List findReplace, Map record) {

OpenOfficeManager openOfficeManager = new OpenOfficeManager();

Map record1 = new HashMap();
record.put("firstname", "Marco");
record.put("lastname", "Silva");
record.put("coordinator", "WILLIS HALE");

List fr = new ArrayList();
FindReplace opt1 = new FindReplace("<>", "firstname");
FindReplace opt2 = new FindReplace("<>", "lastname");
FindReplace opt3 = new FindReplace("<>", "coordinator");
fr.add(opt1);
fr.add(opt2);
fr.add(opt3);

openOfficeManager.openOfficeDocument("file:///home//eanilkumar//",
"Test.doc", fr);
openOfficeManager.replaceDocument(record1);
openOfficeManager.savePDFDocument();

System.out.println(openOfficeManager.GetDocumentText());
openOfficeManager.closeDocument();

}

}

Generic Data Access Objects in hibernate

The DAO interfaces
An implementation with Hibernate
Preparing DAOs with factories
Preparing DAOs with manual dependency injection
Preparing DAOs with lookup
Writing DAOs as managed EJB 3.0 components

This time I based the DAO example on interfaces. Tools like Hibernate already provide database portability, so persistence layer portability shouldn't be a driving motivation for interfaces. However, DAO interfaces make sense in more complex applications, when several persistence services are encapsulate in one persistence layer. I'd say that you should use Hibernate (or Java Persistence APIs) directly in most cases, the best reason to use an additional DAO layer is higher abstraction (e.g. methods like getMaximumBid() instead of session.createQuery(...) repeated a dozen times).

The DAO interfaces

I use one interface per persistent entity, with a super interface for common CRUD functionality:

public interface GenericDAO {

T findById(ID id, boolean lock);

List findAll();

List findByExample(T exampleInstance);

T makePersistent(T entity);

void makeTransient(T entity);
}

You can already see that this is going to be a pattern for a state-oriented data access API, with methods such as makePersistent() and makeTransient(). Furthermore, to implement a DAO you have to provide a type and an identifier argument. As for most ORM solutions, identifier types have to be serializable.

The DAO interface for a particular entity extends the generic interface and provides the type arguments:

public interface ItemDAO extends GenericDAO {

public static final String QUERY_MAXBID = "ItemDAO.QUERY_MAXBID";
public static final String QUERY_MINBID = "ItemDAO.QUERY_MINBID";

Bid getMaxBid(Long itemId);
Bid getMinBid(Long itemId);

}

We basically separate generic CRUD operations and actual business-related data access operations from each other. (Ignore the named query constants for now, they are convenient if you use annotations.) However, even if only CRUD operations are needed for a particular entity, you should still write an interface for it, even it it is going to be empty. It is important to use a concrete DAO in your controller code, otherwise you will face some refactoring once you have to introduce specific data access operations for this entity.

An implementation with Hibernate

An implementation of the interfaces could be done with any state-management capable persistence service. First, the generic CRUD implementation with Hibernate:

public abstract class GenericHibernateDAO
implements GenericDAO {

private Class persistentClass;
private Session session;

public GenericHibernateDAO() {
this.persistentClass = (Class) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}

@SuppressWarnings("unchecked")
public void setSession(Session s) {
this.session = s;
}

protected Session getSession() {
if (session == null)
throw new IllegalStateException("Session has not been set on DAO before usage");
return session;
}

public Class getPersistentClass() {
return persistentClass;
}

@SuppressWarnings("unchecked")
public T findById(ID id, boolean lock) {
T entity;
if (lock)
entity = (T) getSession().load(getPersistentClass(), id, LockMode.UPGRADE);
else
entity = (T) getSession().load(getPersistentClass(), id);

return entity;
}

@SuppressWarnings("unchecked")
public List findAll() {
return findByCriteria();
}

@SuppressWarnings("unchecked")
public List findByExample(T exampleInstance, String[] excludeProperty) {
Criteria crit = getSession().createCriteria(getPersistentClass());
Example example = Example.create(exampleInstance);
for (String exclude : excludeProperty) {
example.excludeProperty(exclude);
}
crit.add(example);
return crit.list();
}

@SuppressWarnings("unchecked")
public T makePersistent(T entity) {
getSession().saveOrUpdate(entity);
return entity;
}

public void makeTransient(T entity) {
getSession().delete(entity);
}

public void flush() {
getSession().flush();
}

public void clear() {
getSession().clear();
}

/**
* Use this inside subclasses as a convenience method.
*/
@SuppressWarnings("unchecked")
protected List findByCriteria(Criterion... criterion) {
Criteria crit = getSession().createCriteria(getPersistentClass());
for (Criterion c : criterion) {
crit.add(c);
}
return crit.list();
}

}

There are some interesting things in this implementation. First, it clearly needs a Session to work, provided with setter injection. You could also use constructor injection. How you set the Session and what scope this Session has is of no concern to the actual DAO implementation. A DAO should not control transactions or the Session scope.

We need to suppress a few compile-time warnings about unchecked casts, because Hibernate's interfaces are JDK 1.4 only. What follows are the implementations of the generic CRUD operations, quite straightforward. The last method is quite nice, using another JDK 5.0 feature, varargs. It helps us to build Criteria queries in concrete entity DAOs. This is an example of a concrete DAO that extends the generic DAO implementation for Hibernate:

public class ItemDAOHibernate
extends GenericHibernateDAO
implements ItemDAO {

public Bid getMaxBid(Long itemId) {
Query q = getSession().getNamedQuery(ItemDAO.QUERY_MAXBID);
q.setParameter("itemid", itemId);
return (Bid) q.uniqueResult();
}

public Bid getMinBid(Long itemId) {
Query q = getSession().getNamedQuery(ItemDAO.QUERY_MINBID);
q.setParameter("itemid", itemId);
return (Bid) q.uniqueResult();
}

}

Another example which uses the findByCriteria() method of the superclass with variable arguments:

public class CategoryDAOHibernate
extends GenericHibernateDAO
implements CategoryDAO {

public Collection findAll(boolean onlyRootCategories) {
if (onlyRootCategories)
return findByCriteria( Expression.isNull("parent") );
else
return findAll();
}
}

Preparing DAOs with factories

We could bring it all together in a DAO factory, which not only sets the Session when a DAO is constructed but also contains nested classes to implement CRUD-only DAOs with no business-related operations:

public class HibernateDAOFactory extends DAOFactory {

public ItemDAO getItemDAO() {
return (ItemDAO)instantiateDAO(ItemDAOHibernate.class);
}

public CategoryDAO getCategoryDAO() {
return (CategoryDAO)instantiateDAO(CategoryDAOHibernate.class);
}

public CommentDAO getCommentDAO() {
return (CommentDAO)instantiateDAO(CommentDAOHibernate.class);
}

public ShipmentDAO getShipmentDAO() {
return (ShipmentDAO)instantiateDAO(ShipmentDAOHibernate.class);
}

private GenericHibernateDAO instantiateDAO(Class daoClass) {
try {
GenericHibernateDAO dao = (GenericHibernateDAO)daoClass.newInstance();
dao.setSession(getCurrentSession());
return dao;
} catch (Exception ex) {
throw new RuntimeException("Can not instantiate DAO: " + daoClass, ex);
}
}

// You could override this if you don't want HibernateUtil for lookup
protected Session getCurrentSession() {
return HibernateUtil.getSessionFactory().getCurrentSession();
}

// Inline concrete DAO implementations with no business-related data access methods.
// If we use public static nested classes, we can centralize all of them in one source file.

public static class CommentDAOHibernate
extends GenericHibernateDAO
implements CommentDAO {}

public static class ShipmentDAOHibernate
extends GenericHibernateDAO
implements ShipmentDAO {}

}

This concrete factory for Hibernate DAOs extends the abstract factory, which is the interface we'll use in application code:

public abstract class DAOFactory {

/**
* Creates a standalone DAOFactory that returns unmanaged DAO
* beans for use in any environment Hibernate has been configured
* for. Uses HibernateUtil/SessionFactory and Hibernate context
* propagation (CurrentSessionContext), thread-bound or transaction-bound,
* and transaction scoped.
*/
public static final Class HIBERNATE = org.hibernate.ce.auction.dao.hibernate.HibernateDAOFactory.class;

/**
* Factory method for instantiation of concrete factories.
*/
public static DAOFactory instance(Class factory) {
try {
return (DAOFactory)factory.newInstance();
} catch (Exception ex) {
throw new RuntimeException("Couldn't create DAOFactory: " + factory);
}
}

// Add your DAO interfaces here
public abstract ItemDAO getItemDAO();
public abstract CategoryDAO getCategoryDAO();
public abstract CommentDAO getCommentDAO();
public abstract ShipmentDAO getShipmentDAO();

}

Note that this factory example is suitable for persistence layers which are primarily implemented with a single persistence service, such as Hibernate or EJB 3.0 persistence. If you have to mix persistence APIs, for example, Hibernate and plain JDBC, the pattern changes slightly. Keep in mind that you can also call session.connection() inside a Hibernate-specific DAO, or use one of the many bulk operation/SQL support options in Hibernate 3.1 to avoid plain JDBC.

Finally, this is how data access now looks like in controller/command handler code (pick whatever transaction demarcation strategy you like, the DAO code doesn't change):

// EJB3 CMT: @TransactionAttribute(TransactionAttributeType.REQUIRED)
public void execute() {

// JTA: UserTransaction utx = jndiContext.lookup("UserTransaction");
// JTA: utx.begin();

// Plain JDBC: HibernateUtil.getCurrentSession().beginTransaction();

DAOFactory factory = DAOFactory.instance(DAOFactory.HIBERNATE);
ItemDAO itemDAO = factory.getItemDAO();
UserDAO userDAO = factory.getUserDAO();

Bid currentMaxBid = itemDAO.getMaxBid(itemId);
Bid currentMinBid = itemDAO.getMinBid(itemId);

Item item = itemDAO.findById(itemId, true);

newBid = item.placeBid(userDAO.findById(userId, false),
bidAmount,
currentMaxBid,
currentMinBid);

// JTA: utx.commit(); // Don't forget exception handling

// Plain JDBC: HibernateUtil.getCurrentSession().getTransaction().commit(); // Don't forget exception handling

}

The database transaction, either JTA or direct JDBC, is started and committed in an interceptor that runs for every execute(), following the Open Session in View pattern. You can use AOP for this or any kind of interceptor that can be wrapped around a method call, see Session handling with AOP.

Preparing DAOs with manual dependency injection

You don't need to write the factories. You can as well just do this:

// EJB3 CMT: @TransactionAttribute(TransactionAttributeType.REQUIRED)
public void execute() {

// JTA: UserTransaction utx = jndiContext.lookup("UserTransaction");
// JTA: utx.begin();

// Plain JDBC: HibernateUtil.getCurrentSession().beginTransaction();

ItemDAOHibernate itemDAO = new ItemDAOHibernate();
itemDAO.setSession(HibernateUtil.getSessionFactory().getCurrentSession());

UserDAOHibernate userDAO = new UserDAOHibernate();
userDAO.setSession(HibernateUtil.getSessionFactory().getCurrentSession());

Bid currentMaxBid = itemDAO.getMaxBid(itemId);
Bid currentMinBid = itemDAO.getMinBid(itemId);

Item item = itemDAO.findById(itemId, true);

newBid = item.placeBid(userDAO.findById(userId, false),
bidAmount,
currentMaxBid,
currentMinBid);

// JTA: utx.commit(); // Don't forget exception handling

// Plain JDBC: HibernateUtil.getCurrentSession().getTransaction().commit(); // Don't forget exception handling

}

The disadvantage here is that the implementation classes (i.e. ItemDAOHibernate and UserDAOHibernate) of the persistence layer are exposed to the client, the controller. Also, constructor injection of the current Session might be more appropriate.

Preparing DAOs with lookup

Alternatively, call HibernateUtil.getSessionFactory().getCurrentSession() as a fallback, if the client didn't provide a Session when the DAO was constructed:

public abstract class GenericHibernateDAO
implements GenericDAO {

private Class persistentClass;
private Session session;

public GenericHibernateDAO() {
this.persistentClass = (Class) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}

public void setSession(Session session) {
this.session = session;
}

protected void getSession() {
if (session == null)
session = HibernateUtil.getSessionFactory().getCurrentSession();
return session;
}

...

The controller now uses these stateless data access objects through direct instantiation:

// EJB3 CMT: @TransactionAttribute(TransactionAttributeType.REQUIRED)
public void execute() {

// JTA: UserTransaction utx = jndiContext.lookup("UserTransaction");
// JTA: utx.begin();

// Plain JDBC: HibernateUtil.getCurrentSession().beginTransaction();

ItemDAO itemDAO = new ItemDAOHibernate();
UserDAO userDAO = new UserDAOHibernate();

Bid currentMaxBid = itemDAO.getMaxBid(itemId);
Bid currentMinBid = itemDAO.getMinBid(itemId);

Item item = itemDAO.findById(itemId, true);

newBid = item.placeBid(userDAO.findById(userId, false),
bidAmount,
currentMaxBid,
currentMinBid);

// JTA: utx.commit(); // Don't forget exception handling

// Plain JDBC: HibernateUtil.getCurrentSession().getTransaction().commit(); // Don't forget exception handling

}

The only disadvantage of this very simple strategy is that the implementation classes (i.e. ItemDAOHibernateUserDAOHibernate) of the persistence layer are again exposed to the client, the controller. You can still supply a custom Session if needed (integration test, etc). and

Each of these methods (factories, manual injection, lookup) for setting the current Session and creating a DAO instance has advantages and drawbacks, use whatever you feel most comfortable with.

Naturally, the cleanest way is managed components and EJB 3.0 session beans:

Writing DAOs as managed EJB 3.0 components

Turn your DAO superclass into a base class for stateless session beans (all your concrete DAOs are then stateless EJBs, they already have a business interface). This is basically a single annotation which you could even move into an XML deployment descriptor if you like. You can then use dependency injection and get the "current" persistence context provided by the container:

@Stateless
public abstract class GenericHibernateDAO
implements GenericDAO {

private Class persistentClass;

@PersistenceContext
private EntityManager em;

public GenericHibernateDAO() {
setSession( (Session)em.getDelegate() );
}

...

You can then cast the delegate of an EntityManager to a Hibernate Session.

This only works if you use Hibernate as a Java Persistence provider, because the delegate is the SessionSession injected directly. If you use a different Java Persistence provider, rely on the EntityManager API instead of Session. Now wire your DAOs into the controller, which is also a managed component: API. In JBoss AS you could even get a

@Stateless
public class ManageAuctionController implements ManageAuction {

@EJB ItemDAO itemDAO;
@EJB UserDAO userDAO;

@TransactionAttribute(TransactionAttributeType.REQUIRED) // This is even the default
public void execute() {

Bid currentMaxBid = itemDAO.getMaxBid(itemId);
Bid currentMinBid = itemDAO.getMinBid(itemId);

Item item = itemDAO.findById(itemId, true);

newBid = item.placeBid(userDAO.findById(userId, false),
bidAmount,
currentMaxBid,
currentMinBid);

}
}

How JAAS enables use of custom security repositories with J2EE applications

This tutorial describes how a developer can write a custom JAASTM LoginModule for using an LDAP authentication data store along with a JavaTM 2 Platform, Enterprise Edition (J2EETM) application.

The tutorial includes a sample implementation of a LDAP based LoginModule which is downloadable as jaastutorial.zip. The archive contains:

  1. jaastutorial.jar
  2. jaasclient.jar
  3. jaastutorial.bat
  4. jaastutorial.sh
  5. login.cfg
The following products were used in creating this tutorial:
  1. Pramati Server 3.0
  2. Pramati Studio 3.0
  3. OpenLDAP 2.0.18
The following specifications apply to this tutorial:
  1. Java Authentication and Authorization ServiceTM 1.0
  2. JavaTM 2 Platform, Enterprise Edition 1.3
  3. Lightweight Directory Access Protocol 3.0

Why JAAS in J2EE
J2EE model: roles, users and JAAS
Writing the JAAS security module
Step 1: Writing the LoginModule
initialize() method
login() method
commit() method
abort() method
logout() method
Exceptions thrown by LoginModule methods
Step 2: Writing the CallBackHandler
Step 3: Configuring the J2EE application
Step 4: Packaging the LoginModule along with application
Step 5: Integrating the LoginModule with the J2EE server
Sample LDAP-based LoginModule
Installing and configuring the OpenLDAP Server
LDAP parameters for LoginModule and User Manager
Configuring LoginModule with Pramati Server
Configuring the User Manager
Creating users and roles from the User Manager
Setting the client classpath
Running the sample
Summary


Why JAAS in J2EE

One of the limitations of J2EE Version 1.2 platform was it did not provide application developers with a standard route to integrating the application server realm with existing or custom security infrastructures. J2EE Version 1.3 now solves that with the inclusion of Java Authentication and Authorization Service (JAAS™) framework.

J2EE application servers that implement JAAS provide enterprise application developers with the standard Login Module API for tapping custom or legacy security systems from their applications. While application developers write to the LoginModule API (specifically, LoginContext API), the application server implements the LoginModule interface.

The standards-based LoginModule interface gives J2EE developers the freedom to tap a variety of information sources that use Java Database Connectivity, the lightweight directory access protocol (LDAP) or Shared File Systems to store authentication data - without requiring them to modify the application code.

Indeed, there are increasing number of scenarios where J2EE application developers wish to tap custom authentication repositories from their applications. They would do this by writing a Login Module, packaging it along with their application and distributing to target J2EE application servers in a prescribed way.

J2EE Model: Roles, Users and JAAS

The J2EE model defines security at two levels: system and application. System level security is defined in terms of User Groups, called Roles, and in terms of security privileges mapping definitions, called Realms. Realms are mappings of one or more User Groups to a set of privileges or permissions.

Application level security is constituted from User Groups and Realms. At the application level, security permissions also list the various application components that are accessible by each User Group in each Realm. Thus, when an application is deployed, its application level realms and roles are mapped to the system level realms and roles defined on the server.

J2EE application servers implementing JAAS enable application developers to write a custom "pluggable" login module in the server environment. Such a module provides a conduit for roles defined in the packaged application to user group information stored in some custom authentication repository, say an LDAP server.


How LoginModule helps application roles and groups map to authentication data stored in a custom repository such as LDAP.
The Role of the LoginModule in J2EE Security Model



Writing the JAAS Security Module

A J2EE application developer writing security with JAAS would basically write the Login Module. The JAAS interface implementation holds the authentication logic. Application servers typically ship with standard Login Module implementations. Application developers may want to write their own implementation, and will see how in this tutorial in the following steps:

  1. Writing the LoginModule interface (LoginContext API)
  2. Writing the CallBackHandler interface that enables client to pass authentication data to the server
  3. Configuring the LoginModule and CallBackHandler with the server and application
  4. Packaging the application along with module classes
  5. Integrating the LoginModule with the application server


Step 1: Writing the LoginModule

In this tutorial, you will see code snippets from a LoginModule implementation for an LDAP Server. We also demonstrate how to test the LDAP LoginModule sample in a typical J2EE application server environment.

This is how the LoginModule implementation class is defined:

 public class LDAPLoginModule implements LoginModule

The standard JAAS packages required by this class are imported as shown here:

 import javax.security.*;
Standards methods in the LoginModule that must be implemented are:
  1. initialize()
  2. login()
  3. commit()
  4. abort()
  5. logout()

initialize()

The initialize method does the following:
  1. Sets configurations required by the LoginModule
  2. Collects login information that is encapsulated in the CallBackHandler
  3. Initializes and instantiates all configuration parameters for this instance of the LoginModule

The client instantiates the LoginContext object and passes a CallBackHandler instance with the user name and password. When the LoginContext object is instantiated, the initialize() method of the LoginModule is triggered.

  public static void main(String args[])
{
LoginContext lc = new LoginContext("Login",
new MyCallbackHandler(args[0],args[1]));
}

login()

This method returns a boolean variable, which is true if the authentication information provided is valid. The login method performs the following tasks:
  1. Fetches the login information
  2. Authenticates the user

The login information is fetched using the CallBackHandler. The code that does this is shown here:

Callback[] calls=new Callback[2];
calls[0]=new NameCallback("name");
calls[1]=new PasswordCallback("Password",false);
callbackHandler.handle(calls);

The login method tries to connect to the server using the login information that is fetched. If the connection is established, the method returns the value true. The following code snippet shows this:

  boolean verification=false;
…try{
props.put(Context.SECURITY_PRINCIPAL,cbUserName);
props.put(Context.SECURITY_CREDENTIALS,cbPassword);
ctx = new InitialDirContext(props);
verification=true;
}…
return verification;

This code changes with the actual type of security framework for which the LoginModule is written.

commit() method

This method sets the subject in the session to the username that is validated by the login method. It also populates the subject with roles specified in the LDAP server (in this tutorial) for that user, and returns true. If the user is not validated, the commit method returns false. The following code snippet shows this:

  if(verification)
{subject.getPrincipals().add(userName);
…subject.getPrincipals().add(role);
return true;
}else return false;

abort() method

This method is used to exit the LoginModule in case of runtime exceptions and is usually triggered by the application server. This method is invoked after the abort() method of LoginContext. The application developer must not directly call the abort method of the LoginContext interface.

logout() method

This method clears the principal settings of the subject in the session. It removes the privilege settings associated with the roles of the subject. The following code snippet shows this:
  subject.getPrincipals().clear();
verification=false;
return true;

Exceptions thrown by LoginModule methods

According to the JAAS specifications, all LoginModule methods should only throw a LoginException. Any other exception during LoginModule execution should be caught and a LoginException thrown against it. The following code snippet shows how this can be done:

   public boolean login() throws LoginException
{

catch(IOException e)
{throw new LoginException(e.toString());}
…}

Step 2: Writing the CallBackHandler

The CallBackHandler is the JAAS interface that defines the type of data used for authentication. For example, a username-password or a user-certificate combination forms a security identity and credential pair. The type of data used for validating the identity is defined as part of the implementation of the CallBackHandler interface.

The CallbackHandler implementation contains a single method, handle(). The following code snippet from the CallBackHandler distributed with the sample client application ClientLoginSample.java demonstrates this:

  static class MyCallbackHandler implements CallbackHandler
{
private String username;
private String password;

The handle() method sets the value of the username and password attributes, passed by the client application, in the LoginModule's CallBackHandler. The following code snippet shows this:

  handle(){

if(callbacks[i] instanceof NameCallback){
NameCallback ncb = (NameCallback)callbacks[i];
ncb.setName(username);}
if(callbacks[i] instanceof PasswordCallback){
PasswordCallback pcb = (PasswordCallback)callbacks[i];
pcb.setPassword(password.toCharArray());
}}

Step 3: Configuring the J2EE application

A J2EE application package includes descriptors that contain information about security privileges for various modules/components of the application. Security privilege is defined at the application level and is associated with realms and roles. During deployment, these roles are mapped to roles defined in the server-level realm.

Configuring a login module with a J2EE application involves the following steps:

  1. Creating a login UI that validates user information by calling the LoginContext interface.
  2. Creating application level realms and roles, and mapping permissions to application components
  3. Distributing the Login Module classes with the application

Step 4: Packaging the Login Module along with Application

A J2EE application developer would want to configure the LoginModule with a target J2EE application server. Therefore, the LoginModule, along with the helper classes, is packaged into a separate JAR file that may be distributed independent of the application archives, and separately loaded from the server classpath.

For this reason, there must be no code-level dependencies in the LoginModule on the J2EE application.

Step 5: Integrating the Login Module with the J2EE Application Server

The deployment process for a LoginModule is unlike J2EE applications and involves configuring the target application server.

A J2EE application server organizes its security environment into realms, each of which maps to one or more login modules, and has one or more users and roles defined on it. This differs from application realms, which are associated with security permissions for the application and do not assume the existence of any LoginModule.

Integrating a LoginModule with the application server involves the following steps:

  1. Configuring the server with a realm that uses a specific LoginModule for security authentication.
  2. Mapping the application realm and roles to the realm and roles defined by the LoginModule.

Sample LDAP-based LoginModule

The tutorial includes a sample implementation of a LDAP based LoginModule. Download the required sample files here (jaastutorial.zip).

We illustrate the steps to integrate this implementation of the LDAP-based LoginModule with Pramati Server using a sample application.

The sample application uses Pramati's implementation of the User Manager Module, which creates users on the LDAP Server and maps roles to various user names defined on the LDAP server. Get the User Manager API here.

Installing and configuring the LDAP server

This tutorial is written assuming a particular directory structure on a LDAP Server.

If you do not have a LDAP Server installed, download one from www.openldap.org. You may access this FTP site. OpenLDAP Server is distributed for Unix/Linux platforms.

Download the Quickstart Guide for LDAP and do as follows to create the required directory structure:

  1. Replace the directory names MY-DOMAIN and example with the name my_company.
  2. In the LDAP server configuration file slapd.conf, set password against the name rootpw as my_password.
  3. Disable the schema checks on the LDAP server by adding the following line to the slapd.conf file: schemacheck off
  4. After configuring the LDAP Server with the directory structure, start the server as instructed in the Quickstart Guide.


LDAP parameters for Login Module and the User Manager


NameValue

LDAPServerUrl The URL and port of the LDAP Server. If the LDAP server is running on the same host as the application server, it would be ldap://localhost:389 (with LDAP Server on port 389)

LDAPContextFactory A default standard context factory implementation is provided by Sun. Set this field ONLY if you are using an other Context Factory. Add the factory to the server classpath too. You will need to restart the server.

Realmname This is the application server-level realm. For example, ldap

LDAPUserKey cn

LDAPUserSuperContext For example, dc=my_company, dc=com

LDAPRolesKey sn

LDAPSuperUserDN For example, cn=manager,dc=my_company,dc=com. This refers to the distinguishing name of the LDAP super user and is set by the LDAP administrator.

LDAPSuperUserPassword The LDAP super user password to the server. This is needed to allow addition and removal of users by the LDAP User Manager.

Configuring LoginModule with Pramati Server

  1. Place the jaastutorial.jar in the classpath of the server by editing the setup.bat.
  2. Run setup.bat from the command line.
  3. Start the Server and then start the Console.
  4. Select the Security node in the tree panel on the Console and select '+' for adding an LDAP realm.
  5. In the View Panel, choose an appropriate server realm name, say, ldap.
  6. Add the path to the LoginModule class as com.pramati.security.loginmodules.ldap.LDAPLoginModule.
  7. Specify the Flag as Required.
  8. The Init options require multiple name-value pairs and these are listed as LDAP parameters in the section above.

Configuring the User Manager

  1. On the same page, give the fully qualified path of the User Manager class as com.pramati.security.loginmodules.ldap.LDAPUserManager
  2. The User Manager needs the same name-value pairs as the LoginModule in the Init Options.

After configuring the LoginModule and the UserManager for the LDAP realm, click on Add button to register the LDAP realm with the application server.

Ensure that the jaastutorial.jar package is present in the server classpath, before starting the server.

Creating users and roles using the User Manager

From the Console, configuring new users with unique user names and passwords, roles within the realm, and mapping the roles and users effectively test the LDAP User Manager Module. If the configuration is correct, new users and their role mappings are added to the realm that can be viewed from the Console.

Setting the client classpath

The ClientLoginSample is a sample Java client that connects to the LDAP server through Pramati Server. The client classpath is modified to point to sample classes and files, as well as the server classes required to run the Java client.

The ClientLoginSample and helper classes are packaged in jaasclient.jar. This must be placed in the client classpath.

The client requires the location of the Pramati Server and the realm to log in to. This information is stored in a file, login.cfg, which is packaged along with this tutorial. This file must be placed in the client classpath.

Edit the login.cfg file to point to the server location and realm name. For example,

  com.pramati.realm="realm://127.0.0.1:9191/ldap"

The client also requires the following application server packages in its classpath:
jaas.jar
jta.jar
pramati_client.jar
security_interop.jar

Edit the file jaastutorial.bat to point to the installation directory of Pramati Server. Run jaastutorial.bat from the command line to set the client classpath.

Running the sample

After setting the client classpath, run the ClientLoginSample program by executing:

  java -Djava.security.auth.login.config=
com.pramati.security.samples.ClientLoginSample
Supply the username and password that has been configured on the LDAP server. The sample program will return the Role to which the User has been mapped. It then logs out the user from the realm. An error message is displayed if the username-password submitted is invalid.

Summary

The tutorial demonstrated the simplicity with which JAAS provides standards based pluggable security. We saw how a custom LoginModule is written and integrated with a typical standards compliant J2EE application server.

Spring Hibernate

Account.java
.....................

package springexample.hibernate;

import java.math.BigDecimal;
import java.util.Date;

public class Account {

private Long id = new Long(-1);

private String accountName;

private String type;

private Double balance;

private Date createDate;

private Date updateDate;

private Customer customer;

public String getAccountName() {
return accountName;
}


public void setAccountName(String accountName) {
this.accountName = accountName;
}



public Date getCreateDate() {
return createDate;
}


public void setCreateDate(Date createDate) {
this.createDate = createDate;
}


public Long getId() {
return id;
}


public void setId(Long id) {
this.id = id;
}


public String getType() {
return type;
}


public void setType(String type) {
this.type = type;
}


public Date getUpdateDate() {
return updateDate;
}


public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}


public Customer getCustomer() {
return customer;
}



public void setCustomer(Customer customer) {
this.customer = customer;
}

public Double getBalance() {
return balance;
}

public void setBalance(Double balance) {
this.balance = balance;
}

}



AccountDAO.java
.............................
package springexample.hibernate;

import java.util.List;


public interface AccountDAO {

public abstract void addAccount(Account account);
}

AccountDAOImpl.java
...................................

package springexample.hibernate;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;

import org.springframework.orm.hibernate.HibernateCallback;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;


public class AccountDAOImpl extends HibernateDaoSupport implements AccountDAO{

public void addAccount(Account account) {
getHibernateTemplate().save(account);
// TODO Auto-generated method stub

}

}


customer.java
................
package springexample.hibernate;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;

public class Customer {

private Long id = new Long(-1);
private String userId;
private String password;
private String email;
private String firstName;
private String lastName;
private BigDecimal balance;

private Set accounts = new HashSet();

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}



public Long getId() {
return id;
}


public void setId(Long id) {
this.id = id;
}

public Set getAccounts() {
return accounts;
}


public void setAccounts(Set accounts) {
this.accounts = accounts;
}

public void addAccount(Account account){
account.setCustomer(this);
accounts.add(account);
}

public BigDecimal getBalance() {
return balance;
}


public void setBalance(BigDecimal balance) {
this.balance = balance;
}


public String getFirstName() {
return firstName;
}


public void setFirstName(String firstName) {
this.firstName = firstName;
}


public String getLastName() {
return lastName;
}


public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getUserId() {
return userId;
}


public void setUserId(String userId) {
this.userId = userId;
}


}

CustomerDAO.java
.................

package springexample.hibernate;

import java.util.List;

public interface CustomerDAO {

public abstract void addCustomer(Customer customer);

public abstract Customer getCustomerAccountInfo(Customer customer);
}
 
CustomerDAOImpl.java
.................
package springexample.hibernate;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import org.springframework.orm.hibernate.HibernateCallback;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
public class CustomerDAOImpl extends HibernateDaoSupport implements CustomerDAO{
public void addCustomer(Customer customer) { getHibernateTemplate().save(customer); // TODO Auto-generated method stub
}
public Customer getCustomerAccountInfo(Customer customer) { Customer cust = null;
List list = getHibernateTemplate().find("from Customer customer " +"where customer.userId = ?" , customer.getUserId(),Hibernate.STRING);
if(list.size() > 0){
cust = (Customer) list.get(0);
}
return cust;
}
}

CreateBankCustomerClient.java
..............................
package springexample.hibernate;
import java.util.ArrayList;
import java.util.Date;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.orm.hibernate.LocalSessionFactoryBean;
public class CreateBankCustomerClient {
public static ClassPathXmlApplicationContext appContext = null;
public static void main(String[] args){
try {
System.out.println("CreateBankCustomerClient started"); ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "springexample-hibernate.xml" }); System.out.println("Classpath loaded");
Customer customer = new Customer(); customer.setEmail("anil.goud@cellarch.com.com"); customer.setUserId("anilkumar"); customer.setPassword("xxxxx");
customer.setFirstName("anil");
customer.setLastName("goud");
Account acc = new Account();
acc.setAccountName("Checking Account-Raj Malhotra"); acc.setType("C");
acc.setCreateDate(new Date());
acc.setUpdateDate(new Date());
acc.setBalance(new Double(500.00));
customer.addAccount(acc);
CustomerDAOImpl customerDAOImpl = (CustomerDAOImpl) appContext.getBean("customerDAOTarget"); customerDAOImpl.addCustomer(customer);
Customer customerRecord = customerDAOImpl.getCustomerAccountInfo(customer);
System.out.println("Customer Found , User Id is " + customerRecord.getUserId());

System.out.println("CreateBankCustomerClient end");
} catch(Exception e){
e.printStackTrace();
}
}
private static void createDatabaseSchema() throws Exception { LocalSessionFactoryBean sessionFactory = (LocalSessionFactoryBean) appContext.getBean("&frameworkSessionFactory"); sessionFactory.dropDatabaseSchema(); sessionFactory.createDatabaseSchema();
}
}


Account.hbm.xml
................

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping>
<class name="springexample.hibernate.Account" table="TBL_ACCOUNT" dynamic-update="false" dynamic-insert="false">
<id name="id" column="ACCOUNT_ID"
type="java.lang.Long" unsaved-value="-1" >
<generator class="native">
</generator> </id>
<many-to-one name="customer"
column="CUSTOMER_ID" class="springexample.hibernate.Customer"
not-null="true"/>
<property name="accountName" type="string"
update="false" insert="true" column="ACCOUNT_NAME"
length="50" not-null="true" />
<property name="type" type="string" update="false" insert="true" column="ACCOUNT_TYPE" length="1" not-null="true" />
<property name="createDate" type="date"
update="false" insert="true" column="CREATE_DATE" not-null="true" />
<property name="updateDate" type="date" update="true" insert="true" not-null="true" column="UPDATE_DATE" /> <property name="balance" type="double" update="true" insert="true"
column="ACCOUNT_BALANCE" not-null="true"/> </class>
</hibernate-mapping>


Customer.hbm.xml
......................


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping>
<class name="springexample.hibernate.Customer" table="TBL_CUSTOMER" dynamic-update="false" dynamic-insert="false"> <id name="id" column="CUSTOMER_ID" type="java.lang.Long" unsaved-value="-1" > <generator class="native"> </generator> </id> <set name ="accounts" inverse = "true" cascade="all-delete-orphan"> <key column ="CUSTOMER_ID"/> <one-to-many class="springexample.hibernate.Account"/> </set> <property name="email" type="string" update="false" insert="true" column="CUSTOMER_EMAIL" length="82" not-null="true" /> <property name="password" type="string" update="false" insert="true" column="CUSTOMER_PASSWORD" length="10" not-null="true" /> <property name="userId" type="string" update="false" insert="true" column="CUSTOMER_USERID" length="12" not-null="true" unique="true" /> <property name="firstName" type="string" update="false" insert="true" column="CUSTOMER_FIRSTNAME" length="25" not-null="true" /> <property name="lastName" type="string" update="false" insert="true" column="CUSTOMER_LASTTNAME" length="25" not-null="true" /> </class> </hibernate-mapping>


springexample-hibernate.xml
.............................


<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <!-- - Application context definition for Express on Hibernate. --> <beans> <bean id="exampleDataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"><value>org.apache.derby.jdbc.EmbeddedDriver
</value></property>
<property name="url"><value>jdbc:derby:springexample;create=true</value></property> </bean> <bean id="exampleHibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="properties"> <props> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.dialect">net.sf.hibernate.dialect.DerbyDialect</prop> <prop key="hibernate.query.substitutions">true 'T', false 'F'</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.c3p0.minPoolSize">5</prop> <prop key="hibernate.c3p0.maxPoolSize">20</prop> <prop key="hibernate.c3p0.timeout">600</prop> <prop key="hibernate.c3p0.max_statement">50</prop> <prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop> </props> </property> </bean> <!-- Hibernate SessionFactory --> <bean id="exampleSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"> <property name="dataSource"><ref local="exampleDataSource"/></property> <property name="hibernateProperties"> <ref bean="exampleHibernateProperties" /> </property> <!-- Must references all OR mapping files. --> <property name="mappingResources"> <list> <value>Customer.hbm.xml</value> <value>Account.hbm.xml</value> </list> </property> </bean> <!-- Pass the session factory to our UserDAO --> <bean id="customerDAOTarget" class="springexample.hibernate.CustomerDAOImpl"> <property name="sessionFactory"><ref local="exampleSessionFactory"/></property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> <property name="sessionFactory"><ref bean="exampleSessionFactory"/></property> </bean> <bean id="userDAO" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref local="transactionManager"/></property> <property name="target"><ref local="customerDAOTarget"/></property> <property name="transactionAttributes"> <props> <prop key="addCustomer">PROPAGATION_REQUIRED</prop> </props> </property> </bean> </beans>

build.xml
............

<project name="springexamples" basedir="." default="main"> <property name="src.dir" value="src"/> <property name="springconf.files" value="src/spring"/> <property name="build.dir" value="build"/> <property name="classes.dir" value="${build.dir}/classes"/> <property name="jar.dir" value="${build.dir}/jar"/> <property name="main-class" value="springexample.hibernate.CreateBankCustomerClient"/> <property name="lib.dir" value="lib"/> <property name="common-lib.dir" value ="C:\spring-framework-1.2-rc2\lib\jakarta-commons"/> <property name="ecache-lib.dir" value ="C:\spring-framework-1.2-rc2\lib\ehcache"/> <property name="dom4j-lib.dir" value ="C:\spring-framework-1.2-rc2\lib\dom4j"/> <property name="cglib-lib.dir" value ="C:\spring-framework-1.2-rc2\lib\cglib"/> <property name="hibernate-lib.dir" value ="C:\spring-framework-1.2-rc2\lib\hibe rnate"/> <property name="jta-lib.dir" value ="C:\spring-framework-1.2-rc2\lib\j2ee"/> <property name="spring-lib.dir" value ="C:\spring-framework-1.2-rc2\dist"/> <property name="ojb-lib.dir" value ="C:\spring-framework-1.2-rc2\lib\ojb"/> <property name="derby-lib.dir" value ="C:\Program Files\IBM\Cloudscape_10.0\lib"/> <path id="classpath"> <fileset dir="${lib.dir}" includes="**/*.jar"/> <fileset dir="${common-lib.dir}" includes="**/*.jar"/> <fileset dir="${ecache-lib.dir}" includes="**/*.jar"/> <fileset dir="${dom4j-lib.dir}" includes="**/*.jar"/> <fileset dir="${cglib-lib.dir}" includes="**/*.jar"/> <fileset dir="${hibernate-lib.dir}" includes="**/*.jar"/> <fileset dir="${jta-lib.dir}" includes="**/*.jar"/> <fileset dir="${spring-lib.dir}" includes="**/*.jar"/> <fileset dir="${ojb-lib.dir} " includes="**/*.jar"/> <fileset dir="${derby-lib.dir}" includes="**/*.jar"/> <path location="${springconf.files}"/> </path> <target name="clean"> <delete dir="${build.dir}"/> </target> <target name="compile"> <mkdir dir="${classes.dir}"/> <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/> </target> <target name="jar" depends="compile"> <mkdir dir="${jar.dir}"/> <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}"> <manifest> <attribute name="Main-Class" value="${main-class}"/> </manifest> </jar> </target> <target name="run" depends="jar"> <java fork="true" classname="${main-class}"> <classpath> <path refid="classpath"/> <path location="${jar.dir}/${ant.project.name}.jar"/> </classpath> </java> </target> <target name="clean-build" depends="clean,jar"/> <target name="main" depends="clean,run"/> </project>







Display File List In a directory

public String[] getFileNames(String DirPath) {

String directoryName;
File directory;
String[] files;
directory = new File(DirPath);
if (directory.isDirectory() == false) {
if (directory.exists() == false) {
System.out.println("There is no such directory!");
return null;

} else {
System.out.println("That file is not a directory.");
return null;
}
} else {
files = directory.list();
// System.out.println("Files in directory -" + directory + "/:");
for (int i = 0; i < files.length; i++) {
//System.out.println(" " + files[i]);

}
return files;
}
}

Date Format in java

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class DateFormat {

static public void displayDate(Locale currentLocale) {

Date today;
String result;
SimpleDateFormat formatter;

formatter = new SimpleDateFormat("EEE d MMM yy", currentLocale);
today = new Date();
result = formatter.format(today);

System.out.println("Locale: " + currentLocale.toString());
System.out.println("Result: " + result);
}

static public void displayPattern(String pattern, Locale currentLocale) {

Date today;
SimpleDateFormat formatter;
String output;

formatter = new SimpleDateFormat(pattern, currentLocale);
today = new Date();
output = formatter.format(today);

System.out.println(pattern + " " + output);
}

static public void main(String[] args) {

Locale[] locales = { new Locale("fr", "FR"), new Locale("de", "DE"),
new Locale("en", "US") };

for (int i = 0; i < locales.length; i++) {
displayDate(locales[i]);
System.out.println();
}

String[] patterns = { "dd.MM.yy", "yyyy.MM.dd G 'at' hh:mm:ss z",
"EEE, MMM d, ''yy", "h:mm a", "H:mm", "H:mm:ss:SSS",
"K:mm a,z", "yyyy.MMMMM.dd GGG hh:mm aaa" };

for (int k = 0; k < patterns.length; k++) {
displayPattern(patterns[k], new Locale("en", "US"));
System.out.println();
}

System.out.println();
}
}

Reading and writing text files


When reading and writing text files :
  • it is almost always a good idea to use buffering (default size is 8K)
  • it is often possible to use references to abstract base classes, instead of references to specific concrete classes
  • there is always a need to pay attention to exceptions (in particular, IOException and FileNotFoundException)
The close method :
  • always needs to be called, or else resources will leak
  • will automatically flush the stream, if necessary
  • calling close on a "wrapper" stream will automatically call close on its underlying stream
  • closing a stream a second time has no consequence
Commonly used items : The FileReader and FileWriter classes always use the system's default character encoding. If this default is not appropriate (for example, when reading an XML file which specifies its own encoding), the recommended alternatives are, for example :

FileInputStream fis = new FileInputStream("test.txt");
InputStreamReader in = new InputStreamReader(fis, "UTF-8");

FileOutputStream fos = new FileOutputStream("test.txt");
OutputStreamWriter out = new OutputStreamWriter(fos, "UTF-8");

Scanner scanner = new Scanner(file, "UTF-8");

Example 1

This example uses JDK 1.4 :

import java.io.*;

public class ReadWriteTextFile {

/**
* Fetch the entire contents of a text file, and return it in a String.
* This style of implementation does not throw Exceptions to the caller.
*
* @param aFile is a file which already exists and can be read.
*/

static public String getContents(File aFile) {
//...checks on aFile are elided
StringBuilder contents = new StringBuilder();

try {
//use buffering, reading one line at a time
//FileReader always assumes default encoding is OK!
BufferedReader input = new BufferedReader(new FileReader(aFile));
try {
String line =
null; //not declared within while loop
/*
* readLine is a bit quirky :
* it returns the content of a line MINUS the newline.
* it returns null only for the END of the stream.
* it returns an empty String if two newlines appear in a row.
*/

while (( line = input.readLine()) != null){
contents.append(line);
contents.append(System.getProperty(
"line.separator"));
}
}
finally {
input.close();
}
}
catch (IOException ex){
ex.printStackTrace();
}

return contents.toString();
}

/**
* Change the contents of text file in its entirety, overwriting any
* existing text.
*
* This style of implementation throws all exceptions to the caller.
*
* @param aFile is an existing file which can be written to.
* @throws IllegalArgumentException if param does not comply.
* @throws FileNotFoundException if the file does not exist.
* @throws IOException if problem encountered during write.
*/

static public void setContents(File aFile, String aContents)
throws FileNotFoundException, IOException {
if (aFile == null) {
throw new IllegalArgumentException("File should not be null.");
}
if (!aFile.exists()) {
throw new FileNotFoundException ("File does not exist: " + aFile);
}
if (!aFile.isFile()) {
throw new IllegalArgumentException("Should not be a directory: " + aFile);
}
if (!aFile.canWrite()) {
throw new IllegalArgumentException("File cannot be written: " + aFile);
}

//use buffering
Writer output = new BufferedWriter(new FileWriter(aFile));
try {
//FileWriter always assumes default encoding is OK!
output.write( aContents );
}
finally {
output.close();
}
}

/** Simple test harness. */
public static void main (String... aArguments) throws IOException {
File testFile =
new File("C:\\Temp\\blah.txt");
System.out.println(
"Original file contents: " + getContents(testFile));
setContents(testFile,
"The content of this file has been overwritten...");
System.out.println(
"New file contents: " + getContents(testFile));
}
}


Example 2

This example demonstrates using Scanner to read a file line by line (it does not perform a write operation) :

import java.io.*;
import java.util.Scanner;

public final class ReadWithScanner {

public static void main(String... aArgs) throws FileNotFoundException {
ReadWithScanner parser =
new ReadWithScanner("C:\\Temp\\test.txt");
parser.processLineByLine();
log(
"Done.");
}

/**
* @param aFileName full name of an existing, readable file.
*/

public ReadWithScanner(String aFileName){
fFile =
new File(aFileName);
}

/** Template method that calls {@link #processLine(String)}. */
public final void processLineByLine() throws FileNotFoundException {
Scanner scanner =
new Scanner(fFile);
try {
//first use a Scanner to get each line
while ( scanner.hasNextLine() ){
processLine( scanner.nextLine() );
}
}
finally {
//ensure the underlying stream is always closed
scanner.close();
}
}

/**
* Overridable method for processing lines in different ways.
*
*

This simple default implementation expects simple name-value pairs, separated by an
* '=' sign. Examples of valid input :
* height = 167cm
* mass = 65kg
* disposition = "grumpy"
* this is the name = this is the value
*/


protected void processLine(String aLine){
//use a second Scanner to parse the content of each line
Scanner scanner = new Scanner(aLine);
scanner.useDelimiter(
"=");
if ( scanner.hasNext() ){
String name = scanner.next();
String value = scanner.next();
log(
"Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim()) );
}
else {
log(
"Empty or invalid line. Unable to process.");
}
//(no need for finally here, since String is source)
scanner.close();
}

// PRIVATE //
private final File fFile;

private static void log(Object aObject){
System.out.println(String.valueOf(aObject));
}

private String quote(String aText){
String QUOTE =
"'";
return QUOTE + aText + QUOTE;
}
}


Example run of this class :
Name is : 'height', and Value is : '167cm'
Name is : 'mass', and Value is : '65kg'
Name is : 'disposition', and Value is : '"grumpy"'
Name is : 'this is the name', and Value is : 'this is the value'
Done.