Tuesday, May 15, 2007

Have a cronjob in a application server?

Objective: The goal is to run a particualr task at regular interval. Ex: We have emails which are stored in a queue and this needs to be sent to all the recipients. There are several options which can be used to solve this problem -
a) Open source frameworks - Jcrontab. We setup the pattern of time when we would like a given task to be executed. (Pre Java 1.3 time)
b) TimerEJB : http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Session5.html
c) TimerTask & Timer (Part of JDK)
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Timer.html

With latest JDK's we can use TimerTask and Timer option as the most simple solution.

Sample Timer:

import java.util.Timer;
import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class EMailService extends Timer
{

private static boolean invokedOnce = false;
private static final Log log = LogFactory.getLog(EMailService.class);
private EMailService() {
}
public static synchronized void initialize(long delay, long period) {

if (!invokedOnce) {
invokedOnce = true;
EMailService mailService = new EMailService();
mailService.schedule(new SendEmail(), delay, period);
log.info("Timed EMailService has been initialized with delay: " + delay + "(ms) period: " + period + "(ms)");
}
}
}

Sample TimerTask: SendMail:

public class SendEmail extends TimerTask {

private static final Log log = LogFactory.getLog(SendEmail.class);

@Override

public void run()
{
long threadId = Thread.currentThread().getId();
...
...
}

How Timer Classes are initializd?

Typically this can be invoked from a Servlet which can be called during startup.

Tuesday, May 8, 2007

Validate XML constructed with DOM parser with XSD

Objective: A XML document is parsed thru DOM and needs to be validated with associated XSD for validity as per the XML schema. Following code snippet shows how:

Code:

public static List validateDOMWithXSD(File domSource, File schemaSource) {
try { // Step 1: create a DocumentBuilderFactory and configure it
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactoryImpl .newInstance();
// Set namespaceAware to true to get a DOM Level 2 tree with nodes // containing namesapce information. This is necessary because the // default value from JAXP 1.0 was defined to be false. documentBuilderFactory.setNamespaceAware(true);
// Set the validation mode to either: no validation, DTD // validation, or XSD validation documentBuilderFactory.setValidating(true); try { documentBuilderFactory.setAttribute( JAXPConstants.JAXP_SCHEMA_LANGUAGE, JAXPConstants.W3C_XML_SCHEMA); } catch (IllegalArgumentException x) { // This can happen if the parser does not support JAXP 1.2 log .error("Error: JAXP DocumentBuilderFactory attribute not recognized: " + JAXPConstants.JAXP_SCHEMA_LANGUAGE); log.error("Check to see if parser conforms to JAXP 1.2 spec."); XMLParseError parseError = new XMLParseError(); parseError .setErrorMessage("Error: JAXP DocumentBuilderFactory attribute not recognized: " + JAXPConstants.JAXP_SCHEMA_LANGUAGE + "\n Check to see if parser conforms to JAXP 1.2 spec.");
errorList = new ArrayList(1); errorList.add(parseError); return errorList; } // Set the schema source, if any. See the JAXP 1.2 maintenance // update specification for more complex usages of this feature.
documentBuilderFactory.setAttribute( JAXPConstants.JAXP_SCHEMA_SOURCE, schemaSource);
// Optional: set various configuration options documentBuilderFactory.setIgnoringComments(false); // documentBuilderFactory.setIgnoringElementContentWhitespace(true);
// documentBuilderFactory.setCoalescing(true);
// The opposite of creating entity ref nodes is expanding them // inline // documentBuilderFactory.setExpandEntityReferences(!createEntityRefs);
// Step 2: create a DocumentBuilder that satisfies the constraints // specified by the DocumentBuilderFactory DocumentBuilder db = documentBuilderFactory.newDocumentBuilder();
// Set an ErrorHandler before parsing errorList = new ArrayList(); db.setErrorHandler(new ParseErrorHandler(errorList));
// Step 3: parse the input file db.parse(domSource);
// return the error list return errorList; } catch (SAXException exception) { return errorList; } catch (Exception exception) { exception.printStackTrace(); } }