All Posts from Februar, 2007

Using Quartz CronTrigger to generate filename timestamps for scheduling

Februar 6th, 2007 | By Christoph in Allgemein, Software-Development | No Comments »

Today we had to generate files which will be importet by another 3rd party system, to import certain XML files from our system.
The other system expected the filenames to follow the a convention:
PREFIX_TIMESTAMP.xml

The timestamp had to be a date following some scheduling rules:
If the other system expects an import file at 10:00 a.m. then the filename has to have PREFIX_20070106-10:00.xml

But now I wanted to have some flexibilty in creating the timestamp.
Our export should run every to hours starting at 9:45 a.m. and the filenames should be
10:00.xml
12:00.xml
14:00.xml
ans so on.

This is when the CronTrigger by the Quartz Scheduler comes into play:
I use the CronTrigger to generate the Timestamps for the filename using this utility function:

public static Calendar getSplitTimeStringByCronExpression(String cronTrigger)
{
Assert.notNull(cronTrigger);
Calendar nextRunTime = Calendar.getInstance();
CronTrigger ct = new CronTrigger();
try {
ct.setCronExpression(cronTrigger);
ct.setStartTime(nextRunTime.getTime());
org.quartz.Calendar quartzCal = new org.quartz.impl.calendar.BaseCalendar();

Date firstFireTime = ct.computeFirstFireTime(quartzCal);
Date nextFireTime = ct.getNextFireTime();

System.out.println(“firstFireTime: ” + firstFireTime);
System.out.println(“nextFireTime: ” + nextFireTime);
nextRunTime.setTime(nextFireTime);

} catch (ParseException e) {
e.printStackTrace();
}
return nextRunTime;
}

An example app would be:

public static void main(String[] args) {
String cronExpression = “0 00 08,10,12,14,16,18,20,22 * * ?”;
Utils.getSplitTimeStringByCronExpression(cronExpression);
}

Calling this function at 9:45 a.m. will result in the output:

firstFireTime: Tue Feb 06 10:00:00 CET 2007
nextFireTime: Tue Feb 06 10:00:00 CET 2007

This is pretty helpful and powerfull, because I can change the behaviour just by defining the cronExpression using this definition
in the class CronTrigger

Castor: Wrap tags in CDATA when Marshalling

Februar 5th, 2007 | By Christoph in Allgemein, Software-Development | No Comments »

I am using Castor to create an XML File for a client. I am using the Castor Sourcecode Generator for Eclipse to create the Object from an XSD.
Everything worked pretty well so far and the XML Output looked quite well – Besides one thing:
I wanted to have the content of a few tags wrapped in a CDATA tag because these tags could have invalid characters which could create problems for the parser.
After googleing around a bit I have found a few sites which came up with a solution.
e.g.
http://webdata.dk/guides/castor-cdata.html
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5011421

This didn’t work instantly for me, because my XML file does not have an own namespace, but is using defaultnamespace:
xmlns=”http://tempuri.org/XMLSchema.xsd”

That is why I had to modify the solution on the given pages, and use the complete url “http://tempuri.org/XMLSchema.xsd” instead of ns1^.

Here is my code which puts CDATA around the tags, which are defined by the variable cdata:

import org.apache.xml.serialize.Method;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.xml.sax.ContentHandler;


Orders orders = tf.process();
Writer writer = new StringWriter();
// Create output format
OutputFormat format = new OutputFormat(Method.XML, “UTF-8″, true);

// Define the names of the XML elements to put CDATA around
String[] cdata = { “http://tempuri.org/XMLSchema.xsd^Comment”,
“http://tempuri.org/XMLSchema.xsd^FirstName”,
“http://tempuri.org/XMLSchema.xsd^LastName”,
“http://tempuri.org/XMLSchema.xsd^Company1″,
“http://tempuri.org/XMLSchema.xsd^Company2″,
“http://tempuri.org/XMLSchema.xsd^Street”,
“http://tempuri.org/XMLSchema.xsd^ZipCode”,
“http://tempuri.org/XMLSchema.xsd^City”,
“http://tempuri.org/XMLSchema.xsd^Phone1″,
“http://tempuri.org/XMLSchema.xsd^Phone2″,
“http://tempuri.org/XMLSchema.xsd^MobilePhone”,
“http://tempuri.org/XMLSchema.xsd^Fax”,
“http://tempuri.org/XMLSchema.xsd^EMail”,
“http://tempuri.org/XMLSchema.xsd^ProductName” };
format.setCDataElements(cdata);
format.setNonEscapingElements(cdata); // Those elements should NOT be escaped..

// Create the serializer
XMLSerializer serializer = new XMLSerializer(writer, format);

// Create the document handler
ContentHandler handler = serializer.asContentHandler();

orders.marshal(handler);
writer.flush();
System.out.println(“xml: ” + writer.toString());
writer.close();

//The rendered Content of orders
StringBuffer sb = new StringBuffer(writer.toString());

Maybe that is helpful for somebody else too.