1
2
3
4
5
6
7
8
9
10
11
12 package sk.uniba.euromath.foRenderer;
13 import javax.xml.namespace.QName;
14 import javax.xml.transform.dom.DOMSource;
15 import org.w3c.dom.Attr;
16 import org.w3c.dom.Element;
17 import org.w3c.dom.NamedNodeMap;
18 import org.w3c.dom.Node;
19 import sk.baka.ikslibs.DOMUtils;
20 import sk.baka.ikslibs.Namespaces;
21 import sk.baka.ikslibs.ids.IDManager;
22 import sk.baka.ikslibs.modify.DOMChangeCollector;
23 import sk.baka.ikslibs.modify.IChangeCollector;
24 import sk.baka.ikslibs.splitted.SplittedDocHolder;
25 import sk.baka.xml.gene.CoordinatorInputKey;
26 import sk.baka.xml.gene.ExportUtils;
27 import sk.uniba.euromath.editor.IInputPreprocessor;
28 /***
29 * Preprocesses the FO renderer input.
30 * @author Martin Vysny
31 */
32 public class FOPreprocessor implements IInputPreprocessor {
33 /***
34 * The renderer receives data using this pipe.
35 */
36 private CoordinatorInputKey input;
37
38
39
40
41 public void init(CoordinatorInputKey input) {
42 if (input == null)
43 throw new IllegalArgumentException("input must not be null");
44 if (this.input != null)
45 throw new IllegalStateException("Already initialized.");
46 this.input = input;
47 }
48
49
50
51
52 public DOMChangeCollector process(IChangeCollector source) {
53
54
55 final Node node = ((DOMChangeCollector) source).getSource().getNode()
56 .cloneNode(true);
57
58
59
60
61
62
63 process(node);
64 final DOMChangeCollector result = new DOMChangeCollector();
65 result.init(new DOMSource(node, source.getSource().getSystemId()));
66
67 return result;
68 }
69 /***
70 * <p>
71 * Processes given node and its children recursively. We have to:
72 * </p>
73 * <ul>
74 * <li>Change <code>emp:id</code> attributes to <code>id</code>
75 * attributes,</li>
76 * <li>Enclose text nodes in <code>fo:inline</code> with correct id, when
77 * processing source document.</li>
78 * </ul>
79 * @param node node to process.
80 */
81 private void process(final Node node) {
82 if (SplittedDocHolder.getGeneRef(node) != null) {
83
84
85
86
87 final Element generef = node.getOwnerDocument().createElementNS(
88 ExportUtils.GENE_ID_ATTRIBUTE_QNAME.getNamespaceURI(),
89 SplittedDocHolder.PI_GENEREF_TARGET);
90 generef.setAttribute("id", SplittedDocHolder.getGeneRef(node));
91 node.getParentNode().replaceChild(generef, node);
92 return;
93 }
94
95 for (Node child = node.getFirstChild(); child != null;) {
96 final Node nextSibling = child.getNextSibling();
97 process(child);
98 child = nextSibling;
99 }
100
101 if (node.getNodeType() == Node.ELEMENT_NODE) {
102
103 final NamedNodeMap atts = node.getAttributes();
104 if (atts != null) {
105 final Attr emidAttr = (Attr) atts.getNamedItemNS(
106 ExportUtils.GENE_ID_ATTRIBUTE_QNAME.getNamespaceURI(),
107 ExportUtils.GENE_ID_ATTRIBUTE_QNAME.getLocalPart());
108 if (emidAttr != null) {
109 atts.removeNamedItemNS(ExportUtils.GENE_ID_ATTRIBUTE_QNAME
110 .getNamespaceURI(),
111 ExportUtils.GENE_ID_ATTRIBUTE_QNAME.getLocalPart());
112 final Attr idAttr = node.getOwnerDocument()
113 .createAttributeNS(null, "id");
114 idAttr.setValue(emidAttr.getValue());
115 atts.setNamedItemNS(idAttr);
116
117
118 }
119 }
120 } else if (node.getNodeType() == Node.TEXT_NODE) {
121
122
123 if (input.info == null) {
124 final Element inline = node.getOwnerDocument().createElementNS(
125 Namespaces.XSL_FO_NAMESPACE, "fo:inline");
126 String id = IDManager.getIDNull(node,
127 ExportUtils.GENE_ID_ATTRIBUTE_QNAME);
128 assert id != null;
129
130
131 id = id + ",N";
132 final Attr idAttr = node.getOwnerDocument().createAttributeNS(
133 null, "id");
134 idAttr.setNodeValue(id);
135 inline.setAttributeNodeNS(idAttr);
136 node.getParentNode().replaceChild(inline, node);
137 inline.appendChild(node);
138 }
139 } else if (node.getNodeType() == Node.CDATA_SECTION_NODE) {
140 throw new IllegalArgumentException("CDATA node occured");
141 } else if (node.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
142 throw new IllegalArgumentException("EntityRef node occured");
143 }
144 }
145
146
147
148
149 public void undo(IChangeCollector source) {
150 throw new AssertionError("Should not be called");
151 }
152 /***
153 * Checks if given node is a generef element and if yes, returns value of
154 * its <code>id</code> attribute.
155 * @param node node to check.
156 * @return non-null value of id attribute if the element is gene-ref
157 * element, <code>null</code> otherwise.
158 */
159 public static String getGenerefElementId(final Node node) {
160 if (node.getNodeType() != Node.ELEMENT_NODE)
161 return null;
162 if (!DOMUtils.equalsNodeQName(node, GENEREF_MARK_ELEMENT))
163 return null;
164 return ((Element) node).getAttribute("id");
165 }
166 /***
167 * The mark element qname.
168 */
169 public static QName GENEREF_MARK_ELEMENT = new QName(
170 ExportUtils.GENE_ID_ATTRIBUTE_QNAME.getNamespaceURI(),
171 SplittedDocHolder.PI_GENEREF_TARGET);
172 }