Salome HOME
SIMAN Eclipse workspace first version
[tools/siman.git] / Workspace / SPlat / src / org / splat / manox / WordXMLDocument.java
1 package org.splat.manox;
2
3 import java.io.File;
4 import java.util.HashMap;
5 import java.util.Vector;
6
7 import org.splat.kernel.XDOM;
8 import org.w3c.dom.Node;
9 import org.w3c.dom.NodeList;
10
11
12 public class WordXMLDocument extends XMLDocument implements Reader, Writer {
13
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
18         
19 //  ==============================================================================================================================
20 //  Constructors
21 //  ==============================================================================================================================
22
23     public WordXMLDocument (File file) throws TypeMismatchException {
24 //  ----------------------------------
25       super(file);
26       if (!isWordDocument()) throw new TypeMismatchException("The file to be open is not a Word document");
27       initializeMe();
28     }
29     protected WordXMLDocument (XMLDocument parse) {  // Downcast internal constructor
30 //  ---------------------------------------------
31       super(parse);
32       initializeMe();                                // The given document is supposed being Word
33     }
34         
35 //  ==============================================================================================================================
36 //  Public services
37 //  ==============================================================================================================================
38
39     public String extractProperty (String name) {
40 //  -------------------------------------------
41       Node property;
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");
45 //    Other properties
46           else {
47         property = capprop.get(name);                // Looking into custom properties first
48         if (property != null)  {
49           property = property.getFirstChild();       // vt:lpwstr node
50         } else {
51           property = binprop.get(name);
52         }
53           }
54       if (property == null) return null;
55       String value = property.getTextContent();
56       if    (value.startsWith("<") && value.endsWith(">"))  value = null;  // Property not set
57       return value;
58     }
59
60     public String extractText () {
61 //  ----------------------------
62       String text = "";
63       if (body != null) {
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);
68       }
69       return text;
70     }
71
72     public String updateProperty (String name, String value) {
73 //  --------------------------------------------------------
74       if (fields == null) {
75           fields = collectFieldNodes(body, new Vector<Node>());
76       }
77 //    Setting of the property
78       Node property = capprop.get(name);             // Looking into custom properties first
79       if  (property != null)  {
80         property = property.getFirstChild();
81       } else {
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());
87       }
88       if (property == null) return null;
89       String oldvalue = property.getTextContent();
90       property.setTextContent(value);
91
92 //    Update of the property fields, if exist
93       String  proname  = " DOCPROPERTY  " + name + " ";
94
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;
99
100                 property = XDOM.getChildNode("w:t", cnode.getFirstChild());
101                 property.setTextContent(value);
102       }
103       return oldvalue;
104     }
105
106     public boolean save () {
107 //  -------------------
108       return XDOM.saveDocument(myfile, myxdoc);
109     }
110
111 //  ==============================================================================================================================
112 //  Private services
113 //  ==============================================================================================================================
114
115     private void initializeMe () {
116 //  ----------------------------
117       loadDocument();                                                // Parses myfile XML document
118
119       body    = mynodes.get("/word/document.xml");
120       capprop = new HashMap<String,Node>();
121       binprop = new HashMap<String,Node>();
122
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;
129           
130           String name = property.getAttributes().getNamedItem("name").getNodeValue();
131           capprop.put(name, property);
132         }
133       }
134       property = mynodes.get("/docProps/core.xml");
135       if  (property != null)  {
136         NodeList  nlist = property.getFirstChild().getChildNodes();  // Contents of cp:coreProperties node
137         String    name;
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
142           
143           String[] parse = name.split(":");
144           binprop.put(parse[1], property);
145         }
146       }
147     }
148
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);                 
156       }
157       return to;
158     }
159
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);                
167       }
168       return to;
169     }
170 }