Consider two possibilities to understand a typical usage and its not about Validation its all about Integration.
1. You wrote a Bug Tracking Application and deployed it at your client, client has a new requirement that when a new bug is created it wants to send its information to other internal System via Web Service.
2. You wrote an Enterprise Application and a new features requires that when a new Product is added to database via JPA Hibernate its details should be sent to other departments via Web Service call.
And this is where the feature kick-ins.
We need to design and implement the capability with these features
- Scalable (should be able to use separate threat to do its job).
- Simple Design and Usable.
- Extendable i.e. No procedural junk code.
Consider following design and Code snippet where Manufacturer and Product are JPA Entities and PartnerXNotifier and PartnerYNotifier are Web Service Clients.
@EntityListeners({EventListener.class})
@Entity
public class Product implements Serializable {
}
@EntityListeners({EventListener.class})
@Entity
public class Manufacturer implements Serializable {
}
public class EventListener {
@PrePersist
public void prePersist(Object object) {
EventObserver.getIntance().prePersist(object);
}
@PostPersist
public void postPersist(Object object) {
EventObserver.getIntance().postPersist(object);
}
@PreUpdate
public void preUpdate(Object object) {
EventObserver.getIntance().preUpdate(object);
}
@PostUpdate
public void postUpdate(Object object) {
EventObserver.getIntance().postUpdate(object);
}
@PreRemove
public void preRemove(Object object) {
EventObserver.getIntance().preRemove(object);
}
@PostLoad
public void postLoad(Object object) {
EventObserver.getIntance().postLoad(object);
}
}
public class EventObserver {
private Map<Class, Set<Handler>> map = new HashMap<Class, Set<Handler>>();
private static final EventObserver observer = new EventObserver();
private EventObserver() {
}
public static EventObserver getIntance() {
return observer;
}
public void clear() {
map = new HashMap<Class, Set<Handler>>();
}
public void loadPropertiesFileOnChange() {
// Todo entity_listener.properties from classpath
// sample file contents
// Product=com.company.project.PartnerXNotifier
// Manufacturer=com.company.project.PartnerYNotifier
}
public void registerHandler(Class clazz, Handler handler) {
Set<Handler> handlers = map.get(clazz);
if (handlers == null) {
handlers = new HashSet<Handler>();
}
handlers.add(handler);
map.put(clazz, handlers);
}
public void prePersist(Object object) {
Set<Handler> set = map.get(object.getClass());
for (Handler handler : set) {
handler.prePersist(object);
}
}
public void postPersist(Object object) {
Set<Handler> set = map.get(object.getClass());
for (Handler handler : set) {
handler.postPersist(object);
}
}
public void preUpdate(Object object) {
}
public void postUpdate(Object object) {
}
public void preRemove(Object object) {
}
public void postLoad(Object object) {
}
}
public interface Handler {
public void prePersist(Object object);
public void postPersist(Object object);
public void preUpdate(Object object);
public void postUpdate(Object object);
public void preRemove(Object object);
public void postLoad(Object object);
}
public class PartnerXNotifier implements Handler {
public void prePersist(Object object) {
// Call the webservice of the partner and pass the object.
}
public void postPersist(Object object) {
}
}
public class PartnerYNotifier extends AbstractHandler {
@Override
public void preRemove(Object object) {
// update partnery webservice
}
}
public abstract class AbstractHandler implements Handler {
public void prePersist(Object object) {}
public void postPersist(Object object) {}
public void preUpdate(Object object) {}
public void postUpdate(Object object) {}
public void preRemove(Object object) {}
public void postLoad(Object object) {}
}
Above design can significantly improve by introducing
- Generics in Handler
- ThreadExecutor in EventObserver
- Properly implementing loadPropertiesFileOnChange() to load properties file from multiple classpath locations
Hope make sense and opens door for seamless integration with other Systems.
Comments