Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
2.4
-
None
-
Patch
Description
Starting with FOP 2.4 the avalon framework is not used anymore.
Instead, a Configuration implementation has been added to the FOP: org.apache.fop.configuration.DefaultConfiguration
The problem is that the getChild(String) method uses getElementsByTagName that returns all matching elements in document order, at any level. The old avalon implementation iterated only through the direct children. This creates some bugs.
Consider the following configuration:
<fop version="1.0"> <!-- .... ---> <renderers> <renderer mime="application/pdf"> <fonts> <auto-detect/> </fonts> </renderer> </renderers> <!-- A substitution can map a font family to another. --> <fonts> <substitutions> <substitution> <from font-family='courierNew' font-style='normal' font-weight='400'/> <to font-family='Courier New'/> </substitution> </substitutions> </fonts> </fop>
The code from the FontManagerConfigurator
DefaultConfiguration fontsCfg = (DefaultConfiguration)cfg.getChild("fonts", false);
now gets the first fonts element, the one containing the autodetect, instead of getting the direct fonts element, the one containing the substitutions.
The patch that solves this is:
Index: DefaultConfiguration.java =================================================================== --- DefaultConfiguration.java (revision 195722) +++ DefaultConfiguration.java (working copy) @@ -108,7 +108,7 @@ @Override public Configuration getChild(String key) { - NodeList nl = element.getElementsByTagName(key); + NodeList nl = element.getChildNodes(); for (int i = 0; i < nl.getLength(); ++i) { Node n = nl.item(i); if (n.getNodeName().equals(key)) { @@ -133,13 +133,17 @@ @Override public Configuration[] getChildren(String key) { - NodeList nl = element.getElementsByTagName(key); - Configuration[] result = new Configuration[nl.getLength()]; + ArrayList<Configuration> result = new ArrayList<>(1); + + NodeList nl = element.getChildNodes(); for (int i = 0; i < nl.getLength(); ++i) { Node n = nl.item(i); - result[i] = new DefaultConfiguration((Element) n); + if (n.getNodeName().equals(key)) { + result.add(new DefaultConfiguration((Element) n)); + } } - return result; + + return result.toArray(new Configuration[0]); } @Override