1 package org.splat.manox;
4 import java.util.HashMap;
5 import java.util.Vector;
7 import org.splat.kernel.XDOM;
8 import org.w3c.dom.Node;
9 import org.w3c.dom.NodeList;
12 public class WordXMLDocument extends XMLDocument implements Reader, Writer {
14 private HashMap<String,Node> binprop; // Built-in properties
15 private HashMap<String,Node> capprop; // Custom application properties
16 private Node body; // Body of the document
17 private Vector<Node> fields = null; // Fields into the document body
19 // ==============================================================================================================================
21 // ==============================================================================================================================
23 public WordXMLDocument (File file) throws TypeMismatchException {
24 // ----------------------------------
26 if (!isWordDocument()) throw new TypeMismatchException("The file to be open is not a Word document");
29 protected WordXMLDocument (XMLDocument parse) { // Downcast internal constructor
30 // ---------------------------------------------
32 initializeMe(); // The given document is supposed being Word
35 // ==============================================================================================================================
37 // ==============================================================================================================================
39 public String extractProperty (String name) {
40 // -------------------------------------------
42 // Properties not conform to the naming scheme
43 if (name.equals("author")) property = binprop.get("creator");
44 else if (name.equals("type")) property = binprop.get("category");
47 property = capprop.get(name); // Looking into custom properties first
48 if (property != null) {
49 property = property.getFirstChild(); // vt:lpwstr node
51 property = binprop.get(name);
54 if (property == null) return null;
55 String value = property.getTextContent();
56 if (value.startsWith("<") && value.endsWith(">")) value = null; // Property not set
60 public String extractText () {
61 // ----------------------------
64 Node body = this.body.getFirstChild(); // w:document node
65 // if (body == null) return text; // Should not happen
66 body = body.getFirstChild(); // w:body node
67 if (body != null) text = extractTextContent(body, text);
72 public String updateProperty (String name, String value) {
73 // --------------------------------------------------------
75 fields = collectFieldNodes(body, new Vector<Node>());
77 // Setting of the property
78 Node property = capprop.get(name); // Looking into custom properties first
79 if (property != null) {
80 property = property.getFirstChild();
82 if (name.equals("author")) property = binprop.get("creator"); // thanks to Bill Gates...
83 else property = binprop.get(name);
84 // Built-in property names are capitalized into the document body (thanks again, Bill Gates)
85 char initial = name.charAt(0);
86 name = name.replaceFirst(String.valueOf(initial), String.valueOf(initial).toUpperCase());
88 if (property == null) return null;
89 String oldvalue = property.getTextContent();
90 property.setTextContent(value);
92 // Update of the property fields, if exist
93 String proname = " DOCPROPERTY " + name + " ";
95 for (int j=0; j<fields.size(); j++) {
96 Node cnode = fields.get(j);
97 String aname = cnode.getAttributes().getNamedItem("w:instr").getNodeValue();
98 if (!aname.startsWith(proname)) continue;
100 property = XDOM.getChildNode("w:t", cnode.getFirstChild());
101 property.setTextContent(value);
106 public boolean save () {
107 // -------------------
108 return XDOM.saveDocument(myfile, myxdoc);
111 // ==============================================================================================================================
113 // ==============================================================================================================================
115 private void initializeMe () {
116 // ----------------------------
117 loadDocument(); // Parses myfile XML document
119 body = mynodes.get("/word/document.xml");
120 capprop = new HashMap<String,Node>();
121 binprop = new HashMap<String,Node>();
123 Node property = mynodes.get("/docProps/custom.xml");
124 if (property != null) {
125 NodeList nlist = property.getFirstChild().getChildNodes(); // Contents of Properties node
126 for (int i=0; i<nlist.getLength(); i++) {
127 property = nlist.item(i);
128 // if (!property.getNodeName().equals("property")) continue;
130 String name = property.getAttributes().getNamedItem("name").getNodeValue();
131 capprop.put(name, property);
134 property = mynodes.get("/docProps/core.xml");
135 if (property != null) {
136 NodeList nlist = property.getFirstChild().getChildNodes(); // Contents of cp:coreProperties node
138 for (int i=0; i<nlist.getLength(); i++) {
139 property = nlist.item(i);
140 name = property.getNodeName();
141 // if (!name.startsWith("dc:")) continue; // Subset of user properties
143 String[] parse = name.split(":");
144 binprop.put(parse[1], property);
149 private Vector<Node> collectFieldNodes (Node from, Vector<Node> to) {
150 // -------------------------------------------------------------------
151 NodeList nlist = from.getChildNodes();
152 for (int i=0; i<nlist.getLength(); i++) {
153 Node cnode = nlist.item(i);
154 if (cnode.getNodeName().equals("w:fldSimple")) to.add(cnode);
155 else to = collectFieldNodes(cnode, to);
160 private String extractTextContent (Node from, String to) {
161 // --------------------------------------------------------
162 NodeList nlist = from.getChildNodes();
163 for (int i=0; i<nlist.getLength(); i++) {
164 Node cnode = nlist.item(i);
165 if (cnode.getNodeName().equals("w:t")) to = to + " " + cnode.getTextContent();
166 else to = extractTextContent(cnode, to);