beans! git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193672 13f79535-47bb-0310-9956-ffa450edef68tags/pre-columns
// FOP | // FOP | ||||
import org.apache.fop.fo.XTFOTreeBuilder; | import org.apache.fop.fo.XTFOTreeBuilder; | ||||
import org.apache.fop.fo.XTElementMapping; | |||||
import org.apache.fop.fo.ElementMapping; | |||||
import org.apache.fop.fo.PropertyListMapping; | import org.apache.fop.fo.PropertyListMapping; | ||||
import org.apache.fop.layout.AreaTree; | import org.apache.fop.layout.AreaTree; | ||||
import org.apache.fop.layout.FontInfo; | import org.apache.fop.layout.FontInfo; | ||||
* | * | ||||
* an element mapping maps element names to Java classes | * an element mapping maps element names to Java classes | ||||
*/ | */ | ||||
public void addElementMapping(XTElementMapping mapping) { | |||||
public void addElementMapping(ElementMapping mapping) { | |||||
mapping.addToBuilder(this.treeBuilder); | mapping.addToBuilder(this.treeBuilder); | ||||
} | } | ||||
* protected method used by addElementMapping(String) to | * protected method used by addElementMapping(String) to | ||||
* instantiate element mapping class | * instantiate element mapping class | ||||
*/ | */ | ||||
protected XTElementMapping createElementMapping(String mappingClassName) { | |||||
protected ElementMapping createElementMapping(String mappingClassName) { | |||||
MessageHandler.logln("using element mapping " + mappingClassName); | MessageHandler.logln("using element mapping " + mappingClassName); | ||||
try { | try { | ||||
return (XTElementMapping) | |||||
return (ElementMapping) | |||||
Class.forName(mappingClassName).newInstance(); | Class.forName(mappingClassName).newInstance(); | ||||
} catch (ClassNotFoundException e) { | } catch (ClassNotFoundException e) { | ||||
MessageHandler.errorln("Could not find " + mappingClassName); | MessageHandler.errorln("Could not find " + mappingClassName); | ||||
* add the element mapping with the given class name | * add the element mapping with the given class name | ||||
*/ | */ | ||||
public void addPropertyList(String listClassName) { | public void addPropertyList(String listClassName) { | ||||
// createPropertyList(listClassName).addToBuilder(this.treeBuilder); | |||||
createPropertyList(listClassName).addToBuilder(this.treeBuilder); | |||||
} | } | ||||
/** | /** |
protected Hashtable unknownFOs = new Hashtable(); | protected Hashtable unknownFOs = new Hashtable(); | ||||
// namespace implementation ideas pinched from John Cowan | // namespace implementation ideas pinched from John Cowan | ||||
protected static class NSMap { | |||||
String prefix; | |||||
String uri; | |||||
int level; | |||||
// protected static class NSMap { | |||||
// String prefix; | |||||
// String uri; | |||||
// int level; | |||||
NSMap(String prefix, String uri, int level) { | |||||
this.prefix = prefix; | |||||
this.uri = uri; | |||||
this.level = level; | |||||
} | |||||
} | |||||
// NSMap(String prefix, String uri, int level) { | |||||
// this.prefix = prefix; | |||||
// this.uri = uri; | |||||
// this.level = level; | |||||
// } | |||||
// } | |||||
protected int level = 0; | |||||
protected Stack namespaceStack = new Stack(); | |||||
// protected int level = 0; | |||||
// protected Stack namespaceStack = new Stack(); | |||||
{ | |||||
namespaceStack.push(new NSMap("xml", | |||||
"http://www.w3.org/XML/1998/namespace", | |||||
-1)); | |||||
namespaceStack.push(new NSMap("", "", -1)); | |||||
} | |||||
// { | |||||
// namespaceStack.push(new NSMap("xml", | |||||
// "http://www.w3.org/XML/1998/namespace", | |||||
// -1)); | |||||
// namespaceStack.push(new NSMap("", "", -1)); | |||||
// } | |||||
protected String findURI(String prefix) { | |||||
for (int i = namespaceStack.size() - 1; i >= 0; i--) { | |||||
NSMap nsMap = (NSMap) (namespaceStack.elementAt(i)); | |||||
if (prefix.equals(nsMap.prefix)) return nsMap.uri; | |||||
} | |||||
return null; | |||||
} | |||||
// protected String findURI(String prefix) { | |||||
// for (int i = namespaceStack.size() - 1; i >= 0; i--) { | |||||
// NSMap nsMap = (NSMap) (namespaceStack.elementAt(i)); | |||||
// if (prefix.equals(nsMap.prefix)) return nsMap.uri; | |||||
// } | |||||
// return null; | |||||
// } | |||||
protected String mapName(String name) | |||||
throws SAXException { | |||||
int colon = name.indexOf(':'); | |||||
String prefix = ""; | |||||
String localPart = name; | |||||
if (colon != -1) { | |||||
prefix = name.substring(0, colon); | |||||
localPart = name.substring(colon + 1); | |||||
} | |||||
String uri = findURI(prefix); | |||||
if (uri == null) { | |||||
if (prefix.equals("")) { | |||||
return name; | |||||
} else { | |||||
throw new SAXException(new FOPException("Unknown namespace prefix " + prefix)); | |||||
} | |||||
} | |||||
return uri + "^" + localPart; | |||||
} | |||||
// protected String mapName(String name) | |||||
// throws SAXException { | |||||
// int colon = name.indexOf(':'); | |||||
// String prefix = ""; | |||||
// String localPart = name; | |||||
// if (colon != -1) { | |||||
// prefix = name.substring(0, colon); | |||||
// localPart = name.substring(colon + 1); | |||||
// } | |||||
// String uri = findURI(prefix); | |||||
// if (uri == null) { | |||||
// if (prefix.equals("")) { | |||||
// return name; | |||||
// } else { | |||||
// throw new SAXException(new FOPException("Unknown namespace prefix " + prefix)); | |||||
// } | |||||
// } | |||||
// return uri + "^" + localPart; | |||||
// } | |||||
/** | /** | ||||
* add a mapping from element name to maker. | * add a mapping from element name to maker. | ||||
String uri, String localName, String rawName) { | String uri, String localName, String rawName) { | ||||
currentFObj.end(); | currentFObj.end(); | ||||
currentFObj = (FObj) currentFObj.getParent(); | currentFObj = (FObj) currentFObj.getParent(); | ||||
level--; | |||||
while (((NSMap) namespaceStack.peek()).level > level) { | |||||
namespaceStack.pop(); | |||||
} | |||||
// level--; | |||||
// while (((NSMap) namespaceStack.peek()).level > level) { | |||||
// namespaceStack.pop(); | |||||
// } | |||||
} | } | ||||
/** SAX Handler for the start of the document */ | /** SAX Handler for the start of the document */ | ||||
/* the maker for the formatting object started */ | /* the maker for the formatting object started */ | ||||
FObj.Maker fobjMaker; | FObj.Maker fobjMaker; | ||||
level++; | |||||
int length = attlist.getLength(); | |||||
for (int i = 0; i < length; i++) { | |||||
String att = attlist.getQName(i); | |||||
if (att.equals("xmlns")) { | |||||
namespaceStack.push( new NSMap("", | |||||
attlist.getValue(i), | |||||
level)); | |||||
} else if (att.startsWith("xmlns:")) { | |||||
String value = attlist.getValue(i); | |||||
namespaceStack.push(new NSMap(att.substring(6), value, | |||||
level)); | |||||
} | |||||
} | |||||
String fullName = mapName(rawName); | |||||
// level++; | |||||
// int length = attlist.getLength(); | |||||
// for (int i = 0; i < length; i++) { | |||||
// String att = attlist.getQName(i); | |||||
// if (att.equals("xmlns")) { | |||||
// namespaceStack.push( new NSMap("", | |||||
// attlist.getValue(i), | |||||
// level)); | |||||
// } else if (att.startsWith("xmlns:")) { | |||||
// String value = attlist.getValue(i); | |||||
// namespaceStack.push(new NSMap(att.substring(6), value, | |||||
// level)); | |||||
// } | |||||
// } | |||||
//String fullName = mapName(rawName); | |||||
String fullName = uri + "^" + localName; | |||||
fobjMaker = (FObj.Maker) fobjTable.get(fullName); | fobjMaker = (FObj.Maker) fobjTable.get(fullName); | ||||
PropertyListBuilder currentListBuilder = (PropertyListBuilder)this.propertylistTable.get(uri); | |||||
PropertyListBuilder currentListBuilder = | |||||
(PropertyListBuilder)this.propertylistTable.get(uri); | |||||
if (fobjMaker == null) { | if (fobjMaker == null) { | ||||
if (!this.unknownFOs.containsKey(fullName)) { | if (!this.unknownFOs.containsKey(fullName)) { | ||||
try { | try { | ||||
PropertyList list = null; | PropertyList list = null; | ||||
if(currentListBuilder != null) { | if(currentListBuilder != null) { | ||||
list = currentListBuilder.makeList(fullName, attlist, | |||||
(currentFObj == null) ? null : currentFObj.properties); | |||||
list = currentListBuilder.makeList(fullName, attlist, | |||||
(currentFObj == null) ? null : currentFObj.properties); | |||||
} | } | ||||
fobj = fobjMaker.make(currentFObj, list); | fobj = fobjMaker.make(currentFObj, list); | ||||
} catch (FOPException e) { | } catch (FOPException e) { |
import org.apache.fop.fo.pagination.Root; | import org.apache.fop.fo.pagination.Root; | ||||
// SAX | // SAX | ||||
import org.xml.sax.HandlerBase; | |||||
import org.xml.sax.SAXException; | import org.xml.sax.SAXException; | ||||
import org.xml.sax.InputSource; | |||||
import org.xml.sax.Attributes; | import org.xml.sax.Attributes; | ||||
import org.xml.sax.helpers.AttributesImpl; | |||||
import org.xml.sax.DocumentHandler; | |||||
import org.xml.sax.AttributeList; | |||||
// Java | // Java | ||||
import java.util.Hashtable; | import java.util.Hashtable; | ||||
/** | /** | ||||
* SAX Handler that builds the formatting object tree. | * SAX Handler that builds the formatting object tree. | ||||
*/ | */ | ||||
public class XTFOTreeBuilder extends HandlerBase { | |||||
/** | |||||
* table mapping element names to the makers of objects | |||||
* representing formatting objects | |||||
*/ | |||||
protected Hashtable fobjTable = new Hashtable(); | |||||
/** | |||||
* class that builds a property list for each formatting object | |||||
*/ | |||||
protected Hashtable propertylistTable = new Hashtable(); | |||||
// protected PropertyListBuilder propertyListBuilder = new | |||||
// PropertyListBuilder(); | |||||
/** | |||||
* current formatting object being handled | |||||
*/ | |||||
protected FObj currentFObj = null; | |||||
/** | |||||
* the root of the formatting object tree | |||||
*/ | |||||
protected FObj rootFObj = null; | |||||
/** | |||||
* set of names of formatting objects encountered but unknown | |||||
*/ | |||||
protected Hashtable unknownFOs = new Hashtable(); | |||||
//public class XTFOTreeBuilder extends HandlerBase { | |||||
public class XTFOTreeBuilder extends FOTreeBuilder | |||||
implements DocumentHandler { | |||||
// namespace implementation ideas pinched from John Cowan | // namespace implementation ideas pinched from John Cowan | ||||
protected static class NSMap { | protected static class NSMap { | ||||
} | } | ||||
protected int level = 0; | protected int level = 0; | ||||
protected String m_uri = null; | |||||
protected String m_localPart = null; | |||||
protected Stack namespaceStack = new Stack(); | protected Stack namespaceStack = new Stack(); | ||||
{ | { | ||||
protected String mapName(String name) | protected String mapName(String name) | ||||
throws SAXException { | throws SAXException { | ||||
int colon = name.indexOf(':'); | int colon = name.indexOf(':'); | ||||
String prefix = ""; | String prefix = ""; | ||||
String localPart = name; | |||||
m_localPart = name; | |||||
if (colon != -1) { | if (colon != -1) { | ||||
prefix = name.substring(0, colon); | prefix = name.substring(0, colon); | ||||
localPart = name.substring(colon + 1); | |||||
m_localPart = name.substring(colon + 1); | |||||
} | } | ||||
String uri = findURI(prefix); | |||||
if (uri == null) { | |||||
m_uri = findURI(prefix); | |||||
if (m_uri == null) { | |||||
if (prefix.equals("")) { | if (prefix.equals("")) { | ||||
return name; | return name; | ||||
} else { | } else { | ||||
throw new SAXException(new FOPException("Unknown namespace prefix " + prefix)); | throw new SAXException(new FOPException("Unknown namespace prefix " + prefix)); | ||||
} | } | ||||
} | } | ||||
return uri + "^" + localPart; | |||||
} | |||||
/** | |||||
* add a mapping from element name to maker. | |||||
* | |||||
* @param namespaceURI namespace URI of formatting object element | |||||
* @param localName local name of formatting object element | |||||
* @param maker Maker for class representing formatting object | |||||
*/ | |||||
public void addMapping(String namespaceURI, String localName, | |||||
FObj.Maker maker) { | |||||
this.fobjTable.put(namespaceURI + "^" + localName, maker); | |||||
} | |||||
/** | |||||
* add a mapping from element name to maker. | |||||
* | |||||
* @param namespaceURI namespace URI of formatting object element | |||||
* @param localName local name of formatting object element | |||||
* @param maker Maker for class representing formatting object | |||||
*/ | |||||
public void addPropertyList(String namespaceURI, Hashtable list) { | |||||
PropertyListBuilder plb; | |||||
plb = (PropertyListBuilder)this.propertylistTable.get(namespaceURI); | |||||
if(plb == null) { | |||||
plb = new PropertyListBuilder(); | |||||
plb.addList(list); | |||||
this.propertylistTable.put(namespaceURI, plb); | |||||
} else { | |||||
plb.addList(list); | |||||
} | |||||
} | |||||
/** | |||||
* add a mapping from element name to maker. | |||||
* | |||||
* @param namespaceURI namespace URI of formatting object element | |||||
* @param localName local name of formatting object element | |||||
* @param maker Maker for class representing formatting object | |||||
*/ | |||||
public void addElementPropertyList(String namespaceURI, String localName, Hashtable list) { | |||||
PropertyListBuilder plb; | |||||
plb = (PropertyListBuilder)this.propertylistTable.get(namespaceURI); | |||||
if(plb == null) { | |||||
plb = new PropertyListBuilder(); | |||||
plb.addElementList(localName, list); | |||||
this.propertylistTable.put(namespaceURI, plb); | |||||
} else { | |||||
plb.addElementList(localName, list); | |||||
} | |||||
} | |||||
/** SAX Handler for characters */ | |||||
public void characters(char data[], int start, int length) { | |||||
currentFObj.addCharacters(data, start, start + length); | |||||
} | |||||
/** SAX Handler for the end of an element */ | |||||
public void endElement( | |||||
String uri, String localName, String rawName) { | |||||
currentFObj.end(); | |||||
currentFObj = (FObj) currentFObj.getParent(); | |||||
level--; | |||||
while (((NSMap) namespaceStack.peek()).level > level) { | |||||
namespaceStack.pop(); | |||||
} | |||||
return m_uri + "^" + m_localPart; | |||||
} | } | ||||
/** SAX Handler for the start of the document */ | |||||
public void startDocument() { | |||||
MessageHandler.logln("building formatting object tree"); | |||||
/** SAX1 Handler for the end of an element */ | |||||
public void endElement(String rawName) throws SAXException { | |||||
mapName(rawName); | |||||
super.endElement(m_uri, m_localPart, rawName); | |||||
level--; | |||||
while (((NSMap) namespaceStack.peek()).level > level) { | |||||
namespaceStack.pop(); | |||||
} | |||||
} | } | ||||
/** SAX Handler for the start of an element */ | |||||
public void startElement(String uri, | |||||
String localName, String rawName, Attributes attlist) | |||||
/** SAX1 Handler for the start of an element */ | |||||
public void startElement(String rawName, AttributeList attlist) | |||||
throws SAXException { | throws SAXException { | ||||
/* the formatting object started */ | |||||
FObj fobj; | |||||
/* the maker for the formatting object started */ | |||||
FObj.Maker fobjMaker; | |||||
// SAX2 version of AttributeList | |||||
AttributesImpl newAttrs = new AttributesImpl(); | |||||
level++; | level++; | ||||
int length = attlist.getLength(); | int length = attlist.getLength(); | ||||
for (int i = 0; i < length; i++) { | for (int i = 0; i < length; i++) { | ||||
String att = attlist.getQName(i); | |||||
String att = attlist.getName(i); | |||||
if (att.equals("xmlns")) { | if (att.equals("xmlns")) { | ||||
namespaceStack.push( new NSMap("", | namespaceStack.push( new NSMap("", | ||||
attlist.getValue(i), | attlist.getValue(i), | ||||
String value = attlist.getValue(i); | String value = attlist.getValue(i); | ||||
namespaceStack.push(new NSMap(att.substring(6), value, | namespaceStack.push(new NSMap(att.substring(6), value, | ||||
level)); | level)); | ||||
} else { | |||||
mapName(att); | |||||
newAttrs.addAttribute(m_uri, m_localPart, att, | |||||
attlist.getType(i), attlist.getValue(i)); | |||||
} | } | ||||
} | |||||
String fullName = mapName(rawName); | |||||
fobjMaker = (FObj.Maker) fobjTable.get(fullName); | |||||
PropertyListBuilder plBuilder = (PropertyListBuilder)this.propertylistTable.get(uri); | |||||
if (fobjMaker == null) { | |||||
if (!this.unknownFOs.containsKey(fullName)) { | |||||
this.unknownFOs.put(fullName, ""); | |||||
MessageHandler.errorln("WARNING: Unknown formatting object " | |||||
+ fullName); | |||||
} | |||||
fobjMaker = new FObjMixed.Maker(); // fall back | |||||
} | |||||
try { | |||||
PropertyList list = plBuilder.makeList(fullName, attlist, | |||||
(currentFObj == null) ? null : currentFObj.properties); | |||||
fobj = fobjMaker.make(currentFObj, list); | |||||
} catch (FOPException e) { | |||||
throw new SAXException(e); | |||||
} | |||||
if (rootFObj == null) { | |||||
rootFObj = fobj; | |||||
if (!fobj.getName().equals("fo:root")) { | |||||
throw new SAXException(new FOPException("Root element must" | |||||
+ " be root, not " | |||||
+ fobj.getName())); | |||||
} | |||||
} else { | |||||
currentFObj.addChild(fobj); | |||||
} | } | ||||
currentFObj = fobj; | |||||
} | |||||
/** | |||||
* format this formatting object tree | |||||
* | |||||
* @param areaTree the area tree to format into | |||||
*/ | |||||
public void format(AreaTree areaTree) | |||||
throws FOPException { | |||||
MessageHandler.logln("formatting FOs into areas"); | |||||
((Root) this.rootFObj).format(areaTree); | |||||
mapName(rawName); | |||||
super.startElement(m_uri, m_localPart, rawName, newAttrs); | |||||
} | } | ||||
} | } |