You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ElementListCheck.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.layoutengine;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import org.w3c.dom.CDATASection;
  22. import org.w3c.dom.Element;
  23. import org.w3c.dom.Node;
  24. import org.w3c.dom.NodeList;
  25. import org.w3c.dom.Text;
  26. import org.apache.fop.layoutmgr.KnuthBox;
  27. import org.apache.fop.layoutmgr.KnuthElement;
  28. import org.apache.fop.layoutmgr.KnuthGlue;
  29. import org.apache.fop.layoutmgr.KnuthPenalty;
  30. /**
  31. * Check implementation that checks a Knuth element list.
  32. */
  33. public class ElementListCheck implements LayoutEngineCheck {
  34. private String category;
  35. private String id;
  36. private int index = -1;
  37. private Element checkElement;
  38. /**
  39. * Creates a new instance from a DOM node.
  40. * @param node DOM node that defines this check
  41. */
  42. public ElementListCheck(Node node) {
  43. this.category = node.getAttributes().getNamedItem("category").getNodeValue();
  44. if (node.getAttributes().getNamedItem("id") != null) {
  45. this.id = node.getAttributes().getNamedItem("id").getNodeValue();
  46. }
  47. if (!haveID()) {
  48. if (node.getAttributes().getNamedItem("index") != null) {
  49. String s = node.getAttributes().getNamedItem("index").getNodeValue();
  50. this.index = Integer.parseInt(s);
  51. }
  52. }
  53. this.checkElement = (Element)node;
  54. }
  55. /**
  56. * @see org.apache.fop.layoutengine.LayoutEngineCheck
  57. */
  58. public void check(LayoutResult result) {
  59. ElementListCollector.ElementList elementList = findElementList(result);
  60. NodeList children = checkElement.getChildNodes();
  61. int pos = -1;
  62. for (int i = 0; i < children.getLength(); i++) {
  63. Node node = children.item(i);
  64. if (node instanceof Element) {
  65. pos++;
  66. Element domEl = (Element)node;
  67. KnuthElement knuthEl = (KnuthElement)elementList.getElementList().get(pos);
  68. if ("skip".equals(domEl.getLocalName())) {
  69. pos += Integer.parseInt(getElementText(domEl)) - 1;
  70. } else if ("box".equals(domEl.getLocalName())) {
  71. if (!(knuthEl instanceof KnuthBox)) {
  72. fail("Expected KnuthBox"
  73. + " at position " + pos
  74. + " but got: " + knuthEl.getClass().getName());
  75. }
  76. if (domEl.getAttribute("w").length() > 0) {
  77. int w = Integer.parseInt(domEl.getAttribute("w"));
  78. if (w != knuthEl.getWidth()) {
  79. fail("Expected w=" + w
  80. + " at position " + pos
  81. + " but got: " + knuthEl.getWidth());
  82. }
  83. }
  84. if ("true".equals(domEl.getAttribute("aux"))) {
  85. if (!knuthEl.isAuxiliary()) {
  86. fail("Expected auxiliary box"
  87. + " at position " + pos);
  88. }
  89. }
  90. if ("false".equals(domEl.getAttribute("aux"))) {
  91. if (knuthEl.isAuxiliary()) {
  92. fail("Expected a normal, not an auxiliary box"
  93. + " at position " + pos);
  94. }
  95. }
  96. } else if ("penalty".equals(domEl.getLocalName())) {
  97. if (!(knuthEl instanceof KnuthPenalty)) {
  98. fail("Expected KnuthPenalty "
  99. + " at position " + pos
  100. + " but got: " + knuthEl.getClass().getName());
  101. }
  102. KnuthPenalty pen = (KnuthPenalty)knuthEl;
  103. if (domEl.getAttribute("w").length() > 0) {
  104. int w = Integer.parseInt(domEl.getAttribute("w"));
  105. if (w != knuthEl.getWidth()) {
  106. fail("Expected w=" + w
  107. + " at position " + pos
  108. + " but got: " + knuthEl.getWidth());
  109. }
  110. }
  111. if (domEl.getAttribute("p").length() > 0) {
  112. if ("<0".equals(domEl.getAttribute("p"))) {
  113. if (knuthEl.getPenalty() >= 0) {
  114. fail("Expected p<0"
  115. + " at position " + pos
  116. + " but got: " + knuthEl.getPenalty());
  117. }
  118. } else if (">0".equals(domEl.getAttribute("p"))) {
  119. if (knuthEl.getPenalty() <= 0) {
  120. fail("Expected p>0"
  121. + " at position " + pos
  122. + " but got: " + knuthEl.getPenalty());
  123. }
  124. } else {
  125. int p;
  126. if ("INF".equalsIgnoreCase(domEl.getAttribute("p"))) {
  127. p = KnuthPenalty.INFINITE;
  128. } else if ("INFINITE".equalsIgnoreCase(domEl.getAttribute("p"))) {
  129. p = KnuthPenalty.INFINITE;
  130. } else if ("-INF".equalsIgnoreCase(domEl.getAttribute("p"))) {
  131. p = -KnuthPenalty.INFINITE;
  132. } else if ("-INFINITE".equalsIgnoreCase(domEl.getAttribute("p"))) {
  133. p = -KnuthPenalty.INFINITE;
  134. } else {
  135. p = Integer.parseInt(domEl.getAttribute("p"));
  136. }
  137. if (p != knuthEl.getPenalty()) {
  138. fail("Expected p=" + p
  139. + " at position " + pos
  140. + " but got: " + knuthEl.getPenalty());
  141. }
  142. }
  143. }
  144. if ("true".equals(domEl.getAttribute("flagged"))) {
  145. if (!pen.isPenaltyFlagged()) {
  146. fail("Expected flagged penalty"
  147. + " at position " + pos);
  148. }
  149. } else if ("false".equals(domEl.getAttribute("flagged"))) {
  150. if (pen.isPenaltyFlagged()) {
  151. fail("Expected non-flagged penalty"
  152. + " at position " + pos);
  153. }
  154. }
  155. if ("true".equals(domEl.getAttribute("aux"))) {
  156. if (!pen.isAuxiliary()) {
  157. fail("Expected auxiliary penalty"
  158. + " at position " + pos);
  159. }
  160. } else if ("false".equals(domEl.getAttribute("aux"))) {
  161. if (pen.isAuxiliary()) {
  162. fail("Expected non-auxiliary penalty"
  163. + " at position " + pos);
  164. }
  165. }
  166. } else if ("glue".equals(domEl.getLocalName())) {
  167. if (!(knuthEl instanceof KnuthGlue)) {
  168. fail("Expected KnuthGlue"
  169. + " at position " + pos
  170. + " but got: " + knuthEl.getClass().getName());
  171. }
  172. KnuthGlue glue = (KnuthGlue)knuthEl;
  173. if (domEl.getAttribute("w").length() > 0) {
  174. int w = Integer.parseInt(domEl.getAttribute("w"));
  175. if (w != knuthEl.getWidth()) {
  176. fail("Expected w=" + w
  177. + " at position " + pos
  178. + " but got: " + knuthEl.getWidth());
  179. }
  180. }
  181. if (domEl.getAttribute("y").length() > 0) {
  182. int stretch = Integer.parseInt(domEl.getAttribute("y"));
  183. if (stretch != knuthEl.getStretch()) {
  184. fail("Expected y=" + stretch
  185. + " (stretch) at position " + pos
  186. + " but got: " + knuthEl.getStretch());
  187. }
  188. }
  189. if (domEl.getAttribute("z").length() > 0) {
  190. int shrink = Integer.parseInt(domEl.getAttribute("z"));
  191. if (shrink != knuthEl.getShrink()) {
  192. fail("Expected z=" + shrink
  193. + " (shrink) at position " + pos
  194. + " but got: " + knuthEl.getShrink());
  195. }
  196. }
  197. } else {
  198. throw new IllegalArgumentException("Invalid child node for 'element-list': "
  199. + domEl.getLocalName()
  200. + " at position " + pos + " (" + this + ")");
  201. }
  202. }
  203. }
  204. pos++;
  205. if (elementList.getElementList().size() > pos) {
  206. fail("There are "
  207. + (elementList.getElementList().size() - pos)
  208. + " unchecked elements at the end of the list");
  209. }
  210. }
  211. private void fail(String msg) {
  212. throw new RuntimeException(msg + " (" + this + ")");
  213. }
  214. private boolean haveID() {
  215. return (this.id != null && this.id.length() > 0);
  216. }
  217. private ElementListCollector.ElementList findElementList(LayoutResult result) {
  218. List candidates = new java.util.ArrayList();
  219. Iterator iter = result.getElementListCollector().getElementLists().iterator();
  220. while (iter.hasNext()) {
  221. ElementListCollector.ElementList el = (ElementListCollector.ElementList)iter.next();
  222. if (el.getCategory().equals(category)) {
  223. if (haveID() && this.id.equals(el.getID())) {
  224. candidates.add(el);
  225. break;
  226. } else if (!haveID()) {
  227. candidates.add(el);
  228. }
  229. }
  230. }
  231. if (candidates.size() == 0) {
  232. throw new ArrayIndexOutOfBoundsException("Requested element list not found");
  233. } else if (index >= 0) {
  234. return (ElementListCollector.ElementList)candidates.get(index);
  235. } else {
  236. return (ElementListCollector.ElementList)candidates.get(0);
  237. }
  238. }
  239. private static String getElementText(Element el) {
  240. StringBuffer sb = new StringBuffer();
  241. NodeList children = el.getChildNodes();
  242. for (int i = 0; i < children.getLength(); i++) {
  243. Node node = children.item(i);
  244. if (node instanceof Text) {
  245. sb.append(((Text)node).getData());
  246. } else if (node instanceof CDATASection) {
  247. sb.append(((CDATASection)node).getData());
  248. }
  249. }
  250. return sb.toString();
  251. }
  252. /** @see java.lang.Object#toString() */
  253. public String toString() {
  254. StringBuffer sb = new StringBuffer("element-list");
  255. sb.append(" category=").append(category);
  256. if (haveID()) {
  257. sb.append(" id=").append(id);
  258. } else if (index >= 0) {
  259. sb.append(" index=").append(index);
  260. }
  261. return sb.toString();
  262. }
  263. }