source: greenstone3/branches/customizingGreenstone3/src/java/org/greenstone/gsdl3/core/Skin.java@ 14713

Last change on this file since 14713 was 14713, checked in by dnk2, 17 years ago

dump of existing code

File size: 12.8 KB
Line 
1package org.greenstone.gsdl3.core;
2
3import java.io.File ;
4import java.io.FileReader;
5
6import org.apache.xerces.parsers.DOMParser;
7import org.greenstone.gsdl3.util.*;
8import org.w3c.dom.*;
9import org.xml.sax.InputSource;
10
11import java.util.*;
12import javax.xml.transform.*;
13import javax.xml.transform.dom.*;
14import javax.xml.transform.stream.*;
15
16
17public class Skin {
18
19 public File rootDirectory ;
20 public Document config ;
21 private Receptionist receptionist ;
22
23 protected DOMParser parser = null;
24 TransformerFactory transformerFactory=null;
25
26 private HashMap<String, String> xsltPagesByAction ;
27
28 public Skin(Page page, Receptionist receptionist) throws Exception{
29
30 this.receptionist = receptionist ;
31 this.transformerFactory = org.apache.xalan.processor.TransformerFactoryImpl.newInstance();
32 transformerFactory.setURIResolver(new MyUriResolver()) ;
33
34 this.parser = new DOMParser();
35 this.parser.setFeature("http://xml.org/sax/features/validation", false);
36 // don't try and load external DTD - no need if we are not validating, and may cause connection errors if a proxy is not set up.
37 this.parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
38 // a performance test showed that having this on lead to increased
39 // memory use for small-medium docs, and not much gain for large
40 // docs.
41 // http://www.sosnoski.com/opensrc/xmlbench/conclusions.html
42 this.parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
43
44
45 String siteHome = GSFile.siteHome(GlobalProperties.getGSDL3Home(), page.getSite()) ;
46 Document collectUi = page.getCollectUi() ;
47
48 if (collectUi != null) {
49 //System.out.println("looking for skin defined at collect level") ;
50
51 String collectHome = GSFile.collectionBaseDir(siteHome, page.getCollection()) ;
52 Element xmlSkin = (Element) GSXML.getChildByTagName(collectUi.getFirstChild(), "skin") ;
53 if (xmlSkin != null) {
54 //System.out.println("skin defined at collect level") ;
55
56 boolean inherit = Boolean.parseBoolean(xmlSkin.getAttribute("inherit")) ;
57
58 if (inherit != true) {
59 boolean local = Boolean.parseBoolean(xmlSkin.getAttribute("local")) ;
60 if (local == true) {
61 rootDirectory = new File(collectHome + File.separatorChar + "ui") ;
62 } else {
63 String name = xmlSkin.getAttribute("name") ;
64 rootDirectory = new File(GlobalProperties.getGSDL3Home() + File.separatorChar + "ui" + File.separatorChar + "skins" + File.separatorChar + File.separatorChar + name) ;
65 }
66 }
67 }
68 }
69
70 Document siteUi = page.getSiteUi() ;
71
72 if (rootDirectory == null && siteUi != null) {
73 //System.out.println("lookding for skin defined at site level") ;
74
75 Element xmlSkin = (Element) GSXML.getChildByTagName(siteUi.getFirstChild(), "skin") ;
76 if (xmlSkin != null) {
77 //System.out.println("skin defined at site level") ;
78 boolean local = Boolean.parseBoolean(xmlSkin.getAttribute("local")) ;
79 if (local == true) {
80 rootDirectory = new File(siteHome + File.separatorChar + "ui") ;
81 } else {
82 String name = xmlSkin.getAttribute("name") ;
83 rootDirectory = new File(GlobalProperties.getGSDL3Home() + File.separatorChar + "ui" + File.separatorChar + "skins" + File.separatorChar + name) ;
84 }
85 }
86 }
87
88 if(rootDirectory == null) {
89 rootDirectory = new File(GlobalProperties.getGSDL3Home() + File.separatorChar + "ui" + File.separatorChar + "skins" + File.separatorChar + "default") ;
90 }
91
92
93 File configFile = new File(rootDirectory.getAbsolutePath() + File.separatorChar + "skin.xml") ;
94 config = receptionist.converter.getDOM(configFile, "utf-8");
95
96
97 // store which xslt pages are responsible for which actions
98
99 xsltPagesByAction = new HashMap() ;
100
101 NodeList actions = config.getElementsByTagName("action") ;
102
103 for (int ai=0 , an=actions.getLength() ; ai<an ; ai++){
104 Element action = (Element) actions.item(ai) ;
105 String a = action.getAttribute("name") ;
106
107 String xsl = action.getAttribute("xslt") ;
108 if (!xsl.equals(""))
109 xsltPagesByAction.put(a, xsl) ;
110
111 NodeList subactions = action.getElementsByTagName("subaction") ;
112
113 for (int si=0 , sn=subactions.getLength() ; si<sn ; si++){
114 Element subaction = (Element) subactions.item(si) ;
115
116 String sa = subaction.getAttribute("name") ;
117 xsl = subaction.getAttribute("xslt") ;
118 xsltPagesByAction.put(a + "_" + sa, xsl) ;
119 }
120 }
121 }
122
123 private Document getXSLTDoc(String action, String subaction) throws Exception {
124 //System.out.println("getting xslt for " + action + ", " + subaction) ;
125
126 String name = xsltPagesByAction.get(action + "_" + subaction) ;
127
128 if (name == null)
129 name = xsltPagesByAction.get(action) ;
130
131 File xslt_file = new File(rootDirectory.getAbsolutePath() + File.separatorChar + "xsl" + File.separatorChar + name) ;
132 //System.out.println("Skinning page using: " + xslt_file) ;
133
134 //if (!xslt_file.canRead())
135 // xslt_file = new File(GlobalProperties.getGSDL3Home() + File.separatorChar + "ui" + File.separatorChar + "xslt" + File.separatorChar + "error.xsl") ;
136
137 FileReader reader = new FileReader(xslt_file);
138 InputSource xml_source = new InputSource(reader);
139 this.parser.parse(xml_source);
140 Document doc = this.parser.getDocument();
141
142 return doc ;
143 }
144
145 private Document getPreprocessDoc() throws Exception {
146
147 File xslt_file = new File(GlobalProperties.getGSDL3Home() + File.separatorChar + "ui" + File.separatorChar + "xslt" + File.separatorChar + "preProcess.xsl") ;
148
149 FileReader reader = new FileReader(xslt_file);
150 InputSource xml_source = new InputSource(reader);
151 this.parser.parse(xml_source);
152 Document doc = this.parser.getDocument();
153
154 return doc ;
155 }
156
157 private Document getLibraryDoc() throws Exception {
158
159 File xslt_file = new File(GlobalProperties.getGSDL3Home() + File.separatorChar + "ui" + File.separatorChar + "xslt" + File.separatorChar + "library.xsl") ;
160
161 FileReader reader = new FileReader(xslt_file);
162 InputSource xml_source = new InputSource(reader);
163 this.parser.parse(xml_source);
164 Document doc = this.parser.getDocument();
165
166 return doc ;
167 }
168
169
170 public Element transformPage(Page page) throws Exception{
171
172 Element p = page.getPage() ;
173 Element pr = page.getPageResponse() ;
174 Element transformedPage = null ;
175
176 Element blah = receptionist.doc.createElement("Skin") ;
177 blah.setAttribute("skinLocation", rootDirectory.getAbsolutePath()) ;
178 pr.appendChild(blah) ;
179
180 Document sourceXml ;
181 try {
182 sourceXml = receptionist.converter.newDOM();
183 sourceXml.appendChild(sourceXml.importNode(p, true));
184 } catch (Exception e) {
185 System.out.println("error loading source data") ;
186 e.printStackTrace() ;
187 return constructErrorPage(e) ;
188 }
189
190 Document skinXsl ;
191 try {
192 skinXsl = getXSLTDoc(page.getAction(), page.getSubaction()) ;
193 } catch (Exception e) {
194 System.out.println("error loading skin xslt") ;
195 e.printStackTrace() ;
196 return constructErrorPage(e) ;
197 }
198
199 Document preprocessingXsl ;
200 try {
201 preprocessingXsl = getPreprocessDoc() ;
202 } catch (Exception e) {
203 System.out.println("error loading preprocessing xslt") ;
204 e.printStackTrace() ;
205 return constructErrorPage(e) ;
206 }
207
208 Document libraryXsl ;
209 try {
210 libraryXsl = getLibraryDoc() ;
211 } catch (Exception e) {
212 System.out.println("error loading preprocessing xslt") ;
213 e.printStackTrace() ;
214 return constructErrorPage(e) ;
215 }
216
217 // combine skin file and library variables/templates into one document.
218 // we dont just use xsl:import because the preprocessing stage needs
219 // to know what's available in the library.
220
221 Document skinAndLibraryXsl ;
222 Document processedXsl = receptionist.converter.newDOM();
223 try {
224
225 skinAndLibraryXsl = receptionist.converter.newDOM();
226 Element root = skinAndLibraryXsl.createElement("skinAndLibraryXsl") ;
227 skinAndLibraryXsl.appendChild(root) ;
228
229 Element s = skinAndLibraryXsl.createElement("skinXsl") ;
230 s.appendChild(skinAndLibraryXsl.importNode(skinXsl.getDocumentElement(), true)) ;
231 root.appendChild(s) ;
232
233 Element l = skinAndLibraryXsl.createElement("libraryXsl") ;
234 l.appendChild(skinAndLibraryXsl.importNode(libraryXsl.getDocumentElement(), true)) ;
235 root.appendChild(l) ;
236
237
238 System.out.println("Pre - processing") ;
239 //pre-process the skin style sheet
240 Transformer preProcessor = transformerFactory.newTransformer(new DOMSource(preprocessingXsl));
241 DOMResult result = new DOMResult();
242 result.setNode(processedXsl) ;
243 preProcessor.transform(new DOMSource(skinAndLibraryXsl), result);
244 } catch (TransformerException e) {
245 return constructErrorPage(e) ;
246 } catch (Exception e) {
247 System.out.println("error preprocessing the skin xslt") ;
248 e.printStackTrace() ;
249 return constructErrorPage(e) ;
250 }
251
252 //return sourceXml.getDocumentElement() ;
253
254 Document finalPage = receptionist.converter.newDOM();
255 //transform source doc
256 try {
257 Transformer transformer = transformerFactory.newTransformer(new DOMSource(processedXsl));
258 DOMResult result = new DOMResult();
259 result.setNode(finalPage) ;
260 transformer.transform(new DOMSource(sourceXml), result);
261 } catch (TransformerException e) {
262 return constructErrorPage(e) ;
263 } catch (Exception e) {
264
265 System.out.println("error transforming page") ;
266 e.printStackTrace() ;
267
268 //return processedXsl.getDocumentElement() ;
269 return constructErrorPage(e) ;
270 }
271
272 return finalPage.getDocumentElement() ;
273 }
274
275 private Element constructErrorPage(TransformerException exception) {
276 Element page = receptionist.doc.createElement("page") ;
277
278 Element header = receptionist.doc.createElement("h1") ;
279 header.setTextContent("Error") ;
280 page.appendChild(header) ;
281
282 Element prompt = receptionist.doc.createElement("p") ;
283 prompt.setTextContent("The following exception occured: ") ;
284 page.appendChild((prompt)) ;
285
286 Element errorXml = receptionist.doc.createElement("code") ;
287 errorXml.setTextContent(exception.getMessageAndLocation()) ;
288 page.appendChild(errorXml) ;
289
290 return page ;
291
292 }
293
294 private Element constructErrorPage(Exception exception) {
295 Element page = receptionist.doc.createElement("page") ;
296
297 Element header = receptionist.doc.createElement("h1") ;
298 header.setTextContent("Error") ;
299 page.appendChild(header) ;
300
301 Element prompt = receptionist.doc.createElement("p") ;
302 prompt.setTextContent("The following exception occured: ") ;
303 page.appendChild((prompt)) ;
304
305 Element errorXml = receptionist.doc.createElement("code") ;
306 errorXml.setTextContent(exception.toString()) ;
307 page.appendChild(errorXml) ;
308
309
310 return page ;
311 }
312
313
314 private Element constructErrorPage(Element source, Document style, Exception exception) {
315 Element page = receptionist.doc.createElement("page") ;
316
317 Element header = receptionist.doc.createElement("h1") ;
318 header.setTextContent("Error") ;
319 page.appendChild(header) ;
320
321 Element prompt = receptionist.doc.createElement("p") ;
322 prompt.setTextContent("The following exception occured: ") ;
323 page.appendChild((prompt)) ;
324
325 Element errorXml = receptionist.doc.createElement("code") ;
326 errorXml.setTextContent(exception.getMessage()) ;
327 page.appendChild(errorXml) ;
328
329 /*
330 Element stackTrace = receptionist.doc.createElement("ul") ;
331
332 StackTraceElement[] st = exception.getStackTrace() ;
333 for (int i=0 ; i< st.length ; i++) {
334 Element ste = receptionist.doc.createElement("li") ;
335 ste.setTextContent(st[i].toString()) ;
336 stackTrace.appendChild(ste) ;
337 }
338 errorMessage.appendChild(stackTrace) ;
339 */
340
341 Element sourceHeader = receptionist.doc.createElement("h2") ;
342 sourceHeader.setTextContent("Source page:") ;
343 page.appendChild(sourceHeader) ;
344
345 Element sourceXml = receptionist.doc.createElement("pre") ;
346 sourceXml.setTextContent(receptionist.converter.getPrettyString(source)) ;
347 page.appendChild(sourceXml) ;
348
349 Element styleHeader = receptionist.doc.createElement("h2") ;
350 styleHeader.setTextContent("Style page:") ;
351 page.appendChild(styleHeader) ;
352
353 Element styleXml = receptionist.doc.createElement("pre") ;
354 styleXml.setTextContent(receptionist.converter.getPrettyString(style)) ;
355 page.appendChild(styleXml) ;
356
357
358 return (Element)page ;
359 }
360
361 private class MyUriResolver implements URIResolver {
362
363 public Source resolve(String href, String base) {
364
365 System.out.println("resolving href='" + href + "', base='" + base + "'") ;
366
367 // check in the skin directory first
368
369 File file = new File(rootDirectory.getAbsolutePath() + File.separatorChar + "xslt" + File.separatorChar + href) ;
370
371 // then check in the xslt library directory
372 if (!file.canRead())
373 file = new File(GlobalProperties.getGSDL3Home() + File.separatorChar + "ui" + File.separatorChar + "xslt" + File.separatorChar + href) ;
374
375 if (file.canRead()) {
376 Source source = new StreamSource(file) ;
377 return source ;
378 } else
379 return null ;
380 }
381
382 }
383
384}
385
Note: See TracBrowser for help on using the repository browser.