Sign in

E-mail *, (xx@domain.com)
Password *

Register | Forgot password

Recent blogs

RSS - Blogs
March 9, 2010
State of OSGi in the Java world
March 4, 2010
Reach more people with Google Translate
March 3, 2010
Get My Advice
February 26, 2010
What? Where!?!
February 11, 2010
Split it!

All Blogs...


Split it!

February 11, 2010

For keeping code maintainable, it is wise to make a clear division between different tasks in a project. The GX WebManager architecture allows such separations to be made in a very clear way: using separate WCBs. However, in practice it might sometimes be difficult to decide in what way to split up functionality and how to keep the code connected. In this post I describe one way of keeping the code connected: the EventManagerService.

The services offered by the EventManagerService are pretty straightforward: services can subscribe to specific events they’re interested in, while other services can publish events when they occur. The EventManagerService makes sure that all services that have subscribed to particular events will be informed when they are published. To illustrate how this works, I’m going to use an example where an external WCB is used to generate PDF files of products as soon as they are updated using the maintenance panel or a periodic synchronization task.

Defining the event

To start, I create a class that holds the information that needs to be sent out when the event occurs. The event must implement the Event interface, such that the EventManagerService can route the events to the correct subscribers. Within my project a generic ValueObject class is used and it is extended for each entity within the domain model. Therefore, I create a generic ValueObjectEvent class that can be used for events regarding any entity type. The implementation of the class is pretty straightforward, so I’ll just leave the ValueObjectEvent.java file up for download.

Publishing the event

As said before, for each entity type there is a class that extends the ValueObject class. This allowed us in the past to create a single DAOHelper class that is used for persistence. I didn’t want to modify this class, as it’s already pretty complex and focuses on the actual persistence, I decided to extend it, such that I only need to override the methods that are actually making changes to the persistent storage.

The overridden methods publish two events for each operation: one event before the persistence operation and one event after. Again, everything is pretty straightforward and I’ve just put up the EventPublishingDAOHelper.java file up for download. At this moment, any change of any entity that is handled by our service can be monitored through by other WCBs through the EventManagementService.

Acting on the event

The only thing left is implementing the service that acts on the interesting events. I wanted to implement this in a separate WCB, because I didn’t want to add a dependency from the product maintenance service WCB to a PDF manipulation library.

In the new WCB, I create a service that overrides the onStart() and onStop() methods and implements the EventHandler interface to subscribe and unsubscribe to the interesting events:

/**
 * {@inheritDoc}
 */
@Override
public void onStart() {
	super.onStart();
	if (myJcrRepository.isReadOnly()) {
		LOG.info("Not starting the PDF generator on a read-only node");
		return;
	}
	myEventManagerService.subscribe(this, Event.Type.POST, Product.class);
}
/**
 * {@inheritDoc}
 */
@Override
public void onStop() {
	super.onStop();
	if (myJcrRepository.isReadOnly()) {
		LOG.info("Not stopping the PDF generator on a read-only node");
		return;
	}
	myEventManagerService.unsubscribe(this, Event.Type.POST, Product.class);
}

Notice that the Product class extends the ValueObject class. Now, any time a product is changed, the onEvent method is fired in my service and again a pretty straightforward implementation determines the correct moments to generate the PDF files, obtains the product object and starts the generation process:

/**
 * {@inheritDoc}
 */
public void onEvent(Event anEvent) {
	try {
		if (anEvent instanceof ValueObjectEvent) {
			ValueObjectEvent event = (ValueObjectEvent) anEvent;
			if (ValueObjectEvent.CREATE.equals(event.getEventAction())
					|| ValueObjectEvent.UPDATE.equals(event.getEventAction())) {
				Object entity = event.getEntity();
				if (entity instanceof Product) {
					Product product = (Product) entity;
					generatePdf(product);
				}
			}
		}
	} catch (IOException e) {
		LOG.log(Level.SEVERE, e.getMessage(), e);
	}
}

About the Author

Return to all blogs


Mark is software engineer with a special interest in Security and Digital WebTV. Mark writes about daily engineering with GX WebManager

Read all Marks blog entries

Other blog entries:

March 3, 2010
Get My Advice
April 22, 2009
What goes in, must come out!
July 29, 2008
WCB Sharing FTW!
June 17, 2008
Found me on LinkedIn?
April 18, 2008
Tosti
April 7, 2008
Baking apple pie at 347
March 21, 2008
Short story about not inventing another wheel
March 13, 2008
Files in and files out
February 29, 2008
Big Brother is watching


Share:

del.icio.us
digg
Technorati
Slashdot
Reddit
YahooMyWeb
NewsVine
ekudos
© 2010 GX creative online development B.V.

Disclaimer

This website (GXdeveloperweb.com) may discuss or contain opinions, (sample) coding, software or other information that does not include GX official interfaces, instructions or guidelines and therefore is not supported by GX. Changes made based on this information are not supported.  GX will not be held liable for any damages caused by using or misusing the information, software, instructions, code or methods suggested on this website, and anyone using these methods does so at his/her own risk. GX offers no guarantees and assumes no responsibility or liability of any type with respect to the content of this website, including any liability resulting from incompatibility between the content of this website and the materials and services offered by GX. By using this website you will not hold, or seek to hold, GX responsible or liable with respect to the content of this website.