1 | package org.honours.greenstone;
|
---|
2 |
|
---|
3 | import java.io.File;
|
---|
4 | import java.io.FileOutputStream;
|
---|
5 | import java.io.OutputStream;
|
---|
6 | import java.io.StringWriter;
|
---|
7 | import java.util.ArrayList;
|
---|
8 | import java.util.List;
|
---|
9 |
|
---|
10 | import javax.xml.transform.Transformer;
|
---|
11 | import javax.xml.transform.TransformerFactory;
|
---|
12 | import javax.xml.transform.dom.DOMSource;
|
---|
13 | import javax.xml.transform.stream.StreamResult;
|
---|
14 |
|
---|
15 | import org.apache.log4j.Logger;
|
---|
16 | import org.expeditee.gui.MessageBay;
|
---|
17 | import org.greenstone.gsdl3.util.GSXML;
|
---|
18 | import org.greenstone.gsdl3.util.XMLConverter;
|
---|
19 | import org.w3c.dom.Document;
|
---|
20 | import org.w3c.dom.Element;
|
---|
21 | import org.w3c.dom.Node;
|
---|
22 | import org.w3c.dom.NodeList;
|
---|
23 |
|
---|
24 | public class CollectionConfigEditor {
|
---|
25 |
|
---|
26 | static Logger logger = Logger.getLogger(org.honours.greenstone.CollectionConfigEditor.class.getName());
|
---|
27 |
|
---|
28 | private XMLConverter _converter;
|
---|
29 | private Document _document;
|
---|
30 |
|
---|
31 | //filename of xml file (collectionConfig.xml) that we want to parse & edit.
|
---|
32 | private String _collectionConfigFile;
|
---|
33 |
|
---|
34 | private Element _displayTag = null;
|
---|
35 | private Element _formatTag = null;
|
---|
36 | private Element _documentContentTemplate = null;
|
---|
37 | private Element _scriptElem = null;
|
---|
38 |
|
---|
39 |
|
---|
40 | private static CollectionConfigEditor _instance = null;
|
---|
41 |
|
---|
42 | public static CollectionConfigEditor getInstance(String c){
|
---|
43 |
|
---|
44 | if(_instance == null)
|
---|
45 | _instance = new CollectionConfigEditor(c);
|
---|
46 |
|
---|
47 | return _instance;
|
---|
48 | }
|
---|
49 |
|
---|
50 | private CollectionConfigEditor(String c){
|
---|
51 | _converter = new XMLConverter();
|
---|
52 | _collectionConfigFile = c;
|
---|
53 |
|
---|
54 | _document = _converter.getDOM(new File(_collectionConfigFile));
|
---|
55 |
|
---|
56 | _displayTag = retrieveDisplayTag();
|
---|
57 | _formatTag = retrieveFormatTag();
|
---|
58 |
|
---|
59 | _documentContentTemplate = retrieveDocContentTemplate();
|
---|
60 | }
|
---|
61 |
|
---|
62 | public void reset(){
|
---|
63 | _instance = null;
|
---|
64 | }
|
---|
65 |
|
---|
66 | /**
|
---|
67 | * Method to retrieve <format></format> element within a
|
---|
68 | * <display></display> element.
|
---|
69 | * @return - the <format></format> element.
|
---|
70 | */
|
---|
71 | public Element getFormatTag(){
|
---|
72 | if(_formatTag != null)
|
---|
73 | return _formatTag;
|
---|
74 | else
|
---|
75 | return retrieveFormatTag();
|
---|
76 | }
|
---|
77 |
|
---|
78 | /**
|
---|
79 | * Method to retrieve a <gsf:template name="documentContent"></gsf:template>
|
---|
80 | * element, generally located in the <display><format>...</format></display>
|
---|
81 | * section of the collectionConfig.xml editor.
|
---|
82 | * @return - the retrieved <gsf:template></gsf:template> element.
|
---|
83 | */
|
---|
84 | public Element getDocumentContentTemplate(){
|
---|
85 | if(_documentContentTemplate != null)
|
---|
86 | return _documentContentTemplate;
|
---|
87 | else
|
---|
88 | return retrieveDocContentTemplate();
|
---|
89 | }
|
---|
90 |
|
---|
91 | /**
|
---|
92 | * Retrieve sectionImage template for displaying
|
---|
93 | * the document image on a GSDL document's page.
|
---|
94 | * @return
|
---|
95 | */
|
---|
96 | public Element getSectionImageTemplate(){
|
---|
97 |
|
---|
98 | Element sectionImageTemplate = null;
|
---|
99 | String xslTemplate = "xsl:template";
|
---|
100 | String sectionImg = "sectionImage";
|
---|
101 |
|
---|
102 |
|
---|
103 | //if an <xsl:template name="sectionImage"></xsl:template> element is found, remove it.
|
---|
104 | getChildElement(_formatTag.getChildNodes(), xslTemplate, "","",sectionImg,_formatTag);
|
---|
105 |
|
---|
106 | //(Re-)create <xsl:template name="sectionImage"></xsl:template>
|
---|
107 | sectionImageTemplate = createElement(xslTemplate, "", sectionImg, "", _formatTag);
|
---|
108 |
|
---|
109 | return sectionImageTemplate;
|
---|
110 | }
|
---|
111 |
|
---|
112 | /**
|
---|
113 | * Searches for, destroys and re-creates an
|
---|
114 | * <xsl:template name="showAssocFilePath"></xsl:template> element.
|
---|
115 | * @return - an <xsl:tempate name="showAssocFilePath"></xsl:template> element.
|
---|
116 | */
|
---|
117 | public Element getAssocFilePathTemplate(){
|
---|
118 |
|
---|
119 | Element assocFilePathTemplate = null;
|
---|
120 | String xslTemplate = "xsl:template";
|
---|
121 | String showAssocFilePath = "showAssocFilePath";
|
---|
122 |
|
---|
123 | getChildElement(_formatTag.getChildNodes(),xslTemplate,"","",showAssocFilePath,_formatTag);
|
---|
124 |
|
---|
125 | assocFilePathTemplate = createElement(xslTemplate,"",showAssocFilePath,"",_formatTag);
|
---|
126 |
|
---|
127 | return assocFilePathTemplate;
|
---|
128 | }
|
---|
129 |
|
---|
130 | /**
|
---|
131 | * NOTE: Don't actually use this at this current time but
|
---|
132 | * will need to later when we want to save Expeditee annotation items
|
---|
133 | * and send these to Greenstone.
|
---|
134 | * @return
|
---|
135 | */
|
---|
136 | public Element getExpediteeAttrTemplate(){
|
---|
137 | return null;
|
---|
138 | }
|
---|
139 |
|
---|
140 | /**
|
---|
141 | * Write out xml to file.
|
---|
142 | */
|
---|
143 | public void write(){
|
---|
144 | try{
|
---|
145 | //System.err.println(GSXML.elementToString(_document.getDocumentElement(), true));
|
---|
146 |
|
---|
147 | TransformerFactory tf = TransformerFactory.newInstance();
|
---|
148 | Transformer trans = tf.newTransformer();
|
---|
149 |
|
---|
150 | //generating string from xml tree
|
---|
151 | StringWriter sw = new StringWriter();
|
---|
152 | StreamResult result = new StreamResult(sw);
|
---|
153 | DOMSource source = new DOMSource(_document);
|
---|
154 | trans.transform(source,result);
|
---|
155 | String xmlString = sw.toString();
|
---|
156 |
|
---|
157 | //Saving the XML content back to collectionConfig.xml
|
---|
158 | OutputStream os = new FileOutputStream(_collectionConfigFile);
|
---|
159 | byte[] buf = xmlString.getBytes();
|
---|
160 |
|
---|
161 | for(int i = 0; i < buf.length; i++){
|
---|
162 | os.write(buf[i]);
|
---|
163 | }
|
---|
164 | os.close();
|
---|
165 | buf = null;
|
---|
166 |
|
---|
167 | }catch(Exception e){
|
---|
168 | e.printStackTrace();
|
---|
169 | return;
|
---|
170 | }
|
---|
171 | }
|
---|
172 |
|
---|
173 | /**
|
---|
174 | * This method searches for and returns a
|
---|
175 | * <display></display> element in the document. If none
|
---|
176 | * exists, a new one will be created.
|
---|
177 | * @return - A <display></display> element.
|
---|
178 | */
|
---|
179 | private Element retrieveDisplayTag(){
|
---|
180 |
|
---|
181 | Element display = null;
|
---|
182 |
|
---|
183 | NodeList nl = _document.getDocumentElement().getElementsByTagName("display");
|
---|
184 |
|
---|
185 | if(nl.getLength() > 0)
|
---|
186 | display = (Element)nl.item(0);
|
---|
187 | else{ //just in case a <display></display> element doesn't exist in the file.
|
---|
188 | display = _document.createElement("display");
|
---|
189 | _document.appendChild(display);
|
---|
190 | }
|
---|
191 |
|
---|
192 | System.err.println(GSXML.elementToString(display, true));
|
---|
193 |
|
---|
194 | return display;
|
---|
195 | }
|
---|
196 |
|
---|
197 | /**
|
---|
198 | * This method returns a <format></format> element found within
|
---|
199 | * a <display></display> element. If none is found, a new
|
---|
200 | * one will be created and returned.
|
---|
201 | * @return - a <format></format> element.
|
---|
202 | */
|
---|
203 | private Element retrieveFormatTag(){
|
---|
204 |
|
---|
205 | Element format = null;
|
---|
206 |
|
---|
207 | //Just in case the display tag hasn't already been retrieved.
|
---|
208 | if(_displayTag != null)
|
---|
209 | _displayTag = retrieveDisplayTag();
|
---|
210 |
|
---|
211 | NodeList nl = _displayTag.getElementsByTagName("format");
|
---|
212 |
|
---|
213 | if(nl.getLength() > 0)
|
---|
214 | format = (Element)nl.item(0);
|
---|
215 | else{
|
---|
216 | format = _document.createElement("format");
|
---|
217 | _displayTag.appendChild(format);
|
---|
218 | }
|
---|
219 |
|
---|
220 | return format;
|
---|
221 | }
|
---|
222 |
|
---|
223 | /**
|
---|
224 | * Returns <gsf:template name="documentContent"></gsf:template>,
|
---|
225 | * located in the <display><format></format></display> section
|
---|
226 | * of the xml file. Customized html will be appended to this
|
---|
227 | * returned element.
|
---|
228 | * @return - a <gsf:template> element with name "documentContent".
|
---|
229 | */
|
---|
230 | private Element retrieveDocContentTemplate(){
|
---|
231 |
|
---|
232 | Element documentContentTemplate = null;
|
---|
233 |
|
---|
234 | String gsfTemplate = "gsf:template";
|
---|
235 | String documentContent = "documentContent";
|
---|
236 |
|
---|
237 | //Obtain script element in documentContent template before deleting template
|
---|
238 | _scriptElem = getScriptTag();
|
---|
239 |
|
---|
240 | //Search for and remove <gsf:template name="documentContent"></gsf:template> then recreate.
|
---|
241 | getChildElement(_formatTag.getChildNodes(),gsfTemplate,"","",documentContent,_formatTag);
|
---|
242 | documentContentTemplate = createElement(gsfTemplate,"",documentContent,"",_formatTag);
|
---|
243 |
|
---|
244 | documentContentTemplate.appendChild(_scriptElem);
|
---|
245 |
|
---|
246 | return documentContentTemplate;
|
---|
247 | }
|
---|
248 |
|
---|
249 | /**
|
---|
250 | * Method to create an element and append it to the passed parent
|
---|
251 | * element.
|
---|
252 | * @param tagname - the element's tagname (e.g. gsf:template)
|
---|
253 | * @param match - a value specifying the "match" attribute, otherwise use ""
|
---|
254 | * @param name - a value specifying the "name" attribute, otherwise use ""
|
---|
255 | * @param mode - a value specifying the "mode" attribute, otherwise use ""
|
---|
256 | * @param parent - the parent element to append the new element to
|
---|
257 | * @return - the newly created element
|
---|
258 | */
|
---|
259 | private Element createElement(String tagname, String match, String name, String mode,Element parent){
|
---|
260 |
|
---|
261 | Element elem = _document.createElement(tagname);
|
---|
262 | parent.appendChild(elem);
|
---|
263 |
|
---|
264 | if(!match.equals(""))
|
---|
265 | elem.setAttribute("match",match);
|
---|
266 |
|
---|
267 | if(!name.equals(""))
|
---|
268 | elem.setAttribute("name",name);
|
---|
269 |
|
---|
270 | if(!mode.equals(""))
|
---|
271 | elem.setAttribute("mode",mode);
|
---|
272 |
|
---|
273 | return elem;
|
---|
274 | }
|
---|
275 |
|
---|
276 |
|
---|
277 | /**
|
---|
278 | * This method searches for a child element that
|
---|
279 | * matches a number of conditions and removes it
|
---|
280 | * from its parent element.
|
---|
281 | * @param nl - the list of elements to search through (a particular element's parents)
|
---|
282 | * @param tagName - the tag name of the element, e.g. gsf:template
|
---|
283 | * @param match - any specified match attribute value, otherwise just use ""
|
---|
284 | * @param mode - any specified mode attribute vale, otherwise just ""
|
---|
285 | * @param name - a name attribute
|
---|
286 | * @param parent - the parent element to remove the child from (if found)
|
---|
287 | */
|
---|
288 | private void getChildElement(NodeList nl, String tagName, String match,String mode, String name, Element parent){
|
---|
289 |
|
---|
290 | for(int i = 0; i < nl.getLength(); i++){
|
---|
291 | Node n = nl.item(i);
|
---|
292 |
|
---|
293 | if(n.getNodeType() == Node.ELEMENT_NODE){
|
---|
294 |
|
---|
295 | if(n.getNodeType() == Node.ELEMENT_NODE){
|
---|
296 |
|
---|
297 | Element e = (Element)n;
|
---|
298 |
|
---|
299 | /* If we find an exact match for elements we want to create, throw
|
---|
300 | * the pre-existing ones away & re-create them and any sub-elements*/
|
---|
301 | boolean tagNameMatches = e.getTagName().equals(tagName);
|
---|
302 |
|
---|
303 | boolean conditionOne = tagNameMatches && e.getAttribute("match").equals(match) &&
|
---|
304 | e.getAttribute("mode").equals(mode);
|
---|
305 | boolean conditionTwo = tagNameMatches && e.getAttribute("name").equals(name);
|
---|
306 |
|
---|
307 |
|
---|
308 | if(conditionOne || conditionTwo)
|
---|
309 | parent.removeChild(e);
|
---|
310 |
|
---|
311 | }
|
---|
312 | }
|
---|
313 | }
|
---|
314 | }
|
---|
315 |
|
---|
316 | /**
|
---|
317 | * This method searches for a <script></script>
|
---|
318 | * element in the documentContent template of the
|
---|
319 | * collectionConfig.xml file.
|
---|
320 | * @return
|
---|
321 | */
|
---|
322 | private Element getScriptTag(){
|
---|
323 |
|
---|
324 | Element script = null;
|
---|
325 |
|
---|
326 | //Obtain <gsf:template name="documentContent"></gsf:template> first.
|
---|
327 | Element docContent = null;
|
---|
328 |
|
---|
329 | NodeList nl = _formatTag.getChildNodes();
|
---|
330 |
|
---|
331 | for(int i = 0; i < nl.getLength(); i++){
|
---|
332 | Node n = nl.item(i);
|
---|
333 |
|
---|
334 | if(n.getNodeType() == Node.ELEMENT_NODE){
|
---|
335 | Element e = (Element)n;
|
---|
336 |
|
---|
337 | if(e.getTagName().equals("gsf:template"))
|
---|
338 | if(e.getAttribute("name").equals("documentContent"))
|
---|
339 | docContent = e;
|
---|
340 |
|
---|
341 | }
|
---|
342 | }
|
---|
343 |
|
---|
344 | if(docContent != null){
|
---|
345 |
|
---|
346 | nl = docContent.getChildNodes();
|
---|
347 |
|
---|
348 | for(int i = 0; i < nl.getLength(); i++){
|
---|
349 |
|
---|
350 | Node n = docContent.getChildNodes().item(i);
|
---|
351 |
|
---|
352 | if(n.getNodeType() == Node.ELEMENT_NODE){
|
---|
353 |
|
---|
354 | Element e = (Element)n;
|
---|
355 |
|
---|
356 | if(e.getTagName().equals("script")){
|
---|
357 |
|
---|
358 | //Check we are only dealing with script element
|
---|
359 | //for adding the export documents to Expeditee feature
|
---|
360 | if(e.getAttribute("id").equals("exportScript")){
|
---|
361 | script = e;
|
---|
362 | }
|
---|
363 | }
|
---|
364 | }
|
---|
365 | }
|
---|
366 |
|
---|
367 | }else{
|
---|
368 | System.err.println("ERROR: No documentContent template could be found while trying to obtain" +
|
---|
369 | "script element.");
|
---|
370 | return null;
|
---|
371 | }
|
---|
372 |
|
---|
373 | //Create a new script element if none can be found.
|
---|
374 | if(script == null)
|
---|
375 | script = generateScriptElement();
|
---|
376 |
|
---|
377 | return script;
|
---|
378 | }
|
---|
379 |
|
---|
380 | private Element generateScriptElement(){
|
---|
381 |
|
---|
382 | //Create a script element with id = "exportScript"
|
---|
383 | Element script = _document.createElement("script");
|
---|
384 | script.setAttribute("text", "text/javascript");
|
---|
385 | script.setAttribute("id","exportScript");
|
---|
386 |
|
---|
387 | //Create <xsl:text> element
|
---|
388 | Element xslText = _document.createElement("xsl:text");
|
---|
389 | xslText.setAttribute("disable-output-escaping","yes");
|
---|
390 | script.appendChild(xslText);
|
---|
391 |
|
---|
392 | String js = writeJSCode();
|
---|
393 |
|
---|
394 | xslText.appendChild(_document.createTextNode(js));
|
---|
395 |
|
---|
396 | return script;
|
---|
397 | }
|
---|
398 |
|
---|
399 | /**
|
---|
400 | * Writes out JS Code for adding the exporting individual
|
---|
401 | * GSDL documents to Expeditee functionality. This code
|
---|
402 | * is stored in a string and returned.
|
---|
403 | * @return -a string containing JS code for the exporting individual
|
---|
404 | * GSDL documents to Expeditee feature.
|
---|
405 | */
|
---|
406 | private String writeJSCode(){
|
---|
407 |
|
---|
408 | StringBuffer jsCode = new StringBuffer("");
|
---|
409 |
|
---|
410 | jsCode.append("$(document).ready(function(){\n");
|
---|
411 | jsCode.append("\t var btnExport = document.createElement(\"button\");\n");
|
---|
412 | jsCode.append("\t $(btnExport).attr('id','btnExport');\n");
|
---|
413 | jsCode.append("\t $(btnExport).attr('class','ui-button ui-widget ui-state-default ui-corner-all');\n");
|
---|
414 | jsCode.append("\t $(btnExport).append(document.createTextNode(\"Export to Expeditee\"));\n\n");
|
---|
415 |
|
---|
416 | jsCode.append("\t $('#rightSidebar').append($(btnExport));\n\n");
|
---|
417 |
|
---|
418 | jsCode.append("\t $('#btnExport').click(function(){\n\n");
|
---|
419 |
|
---|
420 | jsCode.append("\t\t var c = gs.cgiParams.c;\n");
|
---|
421 | jsCode.append("\t\t var docID = gs.cgiParams.d;\n");
|
---|
422 | jsCode.append("\t\t var site = gs.xsltParams.site_name;\n");
|
---|
423 | jsCode.append("\t\t var assocfilepath = gs.documentMetadata.assocfilepath;\n\n");
|
---|
424 |
|
---|
425 | jsCode.append("\t\t var url = 'cgi-bin/export-individual-expeditee.pl?docID=' + docID + '&c=' + '&assocfilepath=' + encodeURIComponent(assocfilepath) + '&site=' + site;\n\n");
|
---|
426 |
|
---|
427 | jsCode.append("\t\t window.open(url,'exportWindow','width=1050,height=700,left=0,top=0,screenX=0,screenY=0');\n");
|
---|
428 |
|
---|
429 | jsCode.append("\t });\n\n");
|
---|
430 |
|
---|
431 | jsCode.append("});");
|
---|
432 |
|
---|
433 |
|
---|
434 | return jsCode.toString();
|
---|
435 | }
|
---|
436 |
|
---|
437 |
|
---|
438 | }
|
---|