source: other-projects/GlamED/trunk/src/org/honours/greenstone/CollectionConfigEditor.java@ 26588

Last change on this file since 26588 was 26588, checked in by davidb, 11 years ago

Initial import of Korii's 520 project for managing digital cultural collections from Greenstone in Expeditee.

File size: 13.1 KB
Line 
1package org.honours.greenstone;
2
3import java.io.File;
4import java.io.FileOutputStream;
5import java.io.OutputStream;
6import java.io.StringWriter;
7import java.util.ArrayList;
8import java.util.List;
9
10import javax.xml.transform.Transformer;
11import javax.xml.transform.TransformerFactory;
12import javax.xml.transform.dom.DOMSource;
13import javax.xml.transform.stream.StreamResult;
14
15import org.apache.log4j.Logger;
16import org.expeditee.gui.MessageBay;
17import org.greenstone.gsdl3.util.GSXML;
18import org.greenstone.gsdl3.util.XMLConverter;
19import org.w3c.dom.Document;
20import org.w3c.dom.Element;
21import org.w3c.dom.Node;
22import org.w3c.dom.NodeList;
23
24public 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 + '&amp;c=' + '&amp;assocfilepath=' + encodeURIComponent(assocfilepath) + '&amp;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}
Note: See TracBrowser for help on using the repository browser.