Codec codec = new Codec(charsetCode);
StringTable stringTable = new StringTable();
StringFactory strings = new StringFactory(codec);
StringReferenceFactory references =
new StringReferenceFactory(stringTable, strings);
WBSAXProcessorContext processorContext =
new WBSAXProcessorContext(
wmlConfiguration.getElementNameFactory(),
wmlConfiguration.getAttributeStartFactory(), strings,
references, charsetEncoding, stringTable,
wmlConfiguration);
// Create the WBSAXDocumentOutputter - this serialises the MCSDOM into
// WBSAX events. This will then be configured for any special
// processing that it needs to do.
wbsaxOutputter = new WBSAXDocumentOutputter(processorContext);
// Set up the null name element processor.
// This will ignore any null name elements introduced into the MCSDOM
// during the DOM optimisation process.
wbsaxOutputter.addSpecialElementProcessor(null,
new WBSAXIgnoreElementProcessor(
processorContext));
// todo: move "final" disassembler here to show accesskeys
// Otherwise it is too late to capture accesskey output properly and
// you will see null data in AccesskeyOpaqueValues rather than the
// appropriate accesskey values which appear in the output (hopefully).
// This will require refactoring since the "final" disassember is
// currently cut and pasted below twice (dissection/none).
// It might be a good idea to add a description to the disassember
// constructor as well since dissection uses multiple disassemblers in
// one pipeline.
// If this protocol supports access key attributes...
if (supportsAccessKeyAttribute) {
// ... then set up the special processing for access keys.
// This is required to calculate access key values when we are
// using numeric shortcut style menus against WML which, unlike
// Openwave, does not support this automagically.
// NOTE: we could slightly improve performance by only doing this
// when actually required, but whether it is worth calculating this
// is not clear at this stage.
//
// This consists of two parts as outlined below.
// First, we add a special element processor to the outputter which
// picks up any special ACCESSKEY-ANNOTATION elements that have
// been inserted into the MCSDOM by the protocol for each element
// which uses an accesskey which requires a calculated value and
// translates them into special opaque WBSAX events during the
// MCSDOM output phase.
boolean doesDeviceDisplayAccesskeyNums =
context.getDevice().getBooleanPolicyValue(DevicePolicyConstants.
SUPPORTS_WML_ACCESSKEY_AUTOMAGIC_NUMBER_DISPLAY);
wbsaxOutputter.addSpecialElementProcessor(
AccesskeyConstants.ACCESSKEY_ANNOTATION_ELEMENT,
new WBSAXAccesskeyAnnotationElementProcessor(processorContext,
!doesDeviceDisplayAccesskeyNums));
// Second, we add a special filter to the producer which picks up
// the special opaque WBSAX events created by the element processor
// above and calculates the appropriate accesskey value as required
// during the WBDOM output phase. This needs to be done here so
// that dissection doesn't end up throwing accesskey values away.
producer = new AccesskeyWBSAXFilter(codec, producer,
wmlConfiguration.getAttributeStartFactory());
}
if (isDissectionNeeded()) {
prepareAndWriteViaDissection(wbsaxOutputter,
producer,
urlListener,
wmlConfiguration,
processorContext,
handler);
}
else {
// We are writing out directly rather than via WBDOM and
// dissection.
StringWriter out = null;
try {
if (logger.isDebugEnabled()) {
out = new StringWriter();
handler = new WBSAXDisassembler(producer, out);
} else {
handler = producer;
}
processorContext.setContentHandler(handler);
// Since we are writing out directly, we must configure the
// WBSAX Outputter to do the things that the dissector would
// normally do.
processorContext.setFinalOutput(true);
processorContext.setUrlListener(urlListener);
wbsaxOutputter.output(document);
} finally {
if (logger.isDebugEnabled()) {
out.flush();