KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejen > EjenStylesheetNode


1 //
2
// Ejen (code generation system)
3
// Copyright (C) 2001, 2002 François Wolff (ejen@noos.fr).
4
//
5
// This file is part of Ejen.
6
//
7
// Ejen is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
11
//
12
// Ejen is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
16
//
17
// You should have received a copy of the GNU General Public License
18
// along with Ejen; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
//
21
package org.ejen;
22
23 import java.util.Vector JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.Properties JavaDoc;
26 import java.io.*;
27 import javax.xml.transform.dom.DOMSource JavaDoc;
28 import javax.xml.transform.stream.StreamSource JavaDoc;
29 import org.apache.xalan.processor.TransformerFactoryImpl;
30 import org.apache.xalan.transformer.TransformerImpl;
31 import org.apache.xalan.templates.StylesheetRoot;
32 import javax.xml.parsers.DocumentBuilder JavaDoc;
33 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
34  
35 import org.w3c.dom.*;
36 // For write operation
37
import javax.xml.transform.Transformer JavaDoc;
38 import javax.xml.transform.TransformerFactory JavaDoc;
39 import javax.xml.transform.stream.StreamResult JavaDoc;
40
41 /**
42  * Parent abstract class of all Ejen...Node classes that use a stylesheet
43  * (filter, template, include and import).
44  * @author F. Wolff
45  * @version 1.0
46  */

47 public abstract class EjenStylesheetNode extends EjenChildNode {
48     private String JavaDoc stylesheet = "";
49     
50     protected Vector JavaDoc _childNodes = new Vector JavaDoc();
51     protected String JavaDoc _file = null;
52
53     /**
54      * Returns all non null attributes of this EjenStylesheetNode.
55      * @return non null attributes of this EjenStylesheetNode.
56      */

57     public Properties JavaDoc getAttributes() {
58         Properties JavaDoc attrs = super.getAttributes();
59
60         if (_file != null) {
61             attrs.setProperty("file", _file);
62         }
63         return attrs;
64     }
65
66     /**
67      * Returns all child nodes of this EjenStylesheetNode (include, import or
68      * param).
69      * @return all child nodes of this EjenStylesheetNode.
70      */

71     public Vector JavaDoc getChildren() {
72         Vector JavaDoc children = super.getChildren();
73
74         children.addAll(_childNodes);
75         return children;
76     }
77
78     /**
79      * <b>[mandatory/AVT]</b> - sets the file attribute.
80      * @param file name of the XSL file stylesheet to be used as filter, template,
81      * include or import.
82      */

83     public void setFile(String JavaDoc file) {
84         this.transformInputFile(file);
85         _file = file;
86     }
87
88     /**
89      * Creates a new param node and appends it to the list of current child
90      * nodes of this EjenStylesheetNode.
91      * @return the new param node.
92      */

93     public EjenParamNode createParam() {
94         EjenParamNode p = new EjenParamNode();
95
96         _childNodes.addElement(p);
97         return p;
98     }
99
100     /**
101      * Creates a new include node and appends it to the list of current child
102      * nodes of this EjenStylesheetNode.
103      * @return the new include node.
104      */

105     public EjenIncludeNode createInclude() {
106         EjenIncludeNode i = new EjenIncludeNode();
107
108         _childNodes.addElement(i);
109         return i;
110     }
111
112     /**
113      * Creates a new import node and appends it to the list of current child
114      * nodes of this EjenStylesheetNode.
115      * @return the new import node.
116      */

117     public EjenImportNode createImport() {
118         EjenImportNode i = new EjenImportNode();
119
120         _childNodes.addElement(i);
121         return i;
122     }
123
124     /**
125      * Checks this EjenStylesheetNode for mandatory attributes.
126      * @throws org.ejen.EjenException if file attribute is not set or if any
127      * call to the check() method of a child node fails.
128      */

129     public void check() {
130         super.check();
131         if (_file == null) {
132             throw new EjenException(this, "no 'file' attribute");
133         }
134         for (Enumeration JavaDoc e = _childNodes.elements(); e.hasMoreElements();) {
135             ((EjenChildNode) e.nextElement()).check();
136         }
137     }
138
139     /**
140      * Prepares this EjenStylesheetNode execution. Creates a new Transformer with
141      * the stylesheet whose name is provided by the file attribute and pushes a
142      * new context onto the context stack.
143      */

144     public void beforeProcess() {
145         super.beforeProcess();
146         
147         TransformerFactoryImpl tfi = null;
148
149         try {
150             tfi = (TransformerFactoryImpl) (getFromGlobalContext(CTX_TRANSFORMER_FACTORY_IMPL));
151         } catch (Exception JavaDoc e) {
152             throw new EjenException(this, null, e);
153         }
154         if (tfi == null) {
155             throw new EjenException(this,
156                     "no '" + CTX_TRANSFORMER_FACTORY_IMPL
157                     + "' in global context");
158         }
159         InputStream inputs = null;
160
161         try {
162             inputs = new FileInputStream(evaluateAVT(_file));
163             TransformerImpl ti = (TransformerImpl) (tfi.newTransformer(new StreamSource JavaDoc(inputs)));
164             EjenContext newContext = cloneContext();
165
166             newContext.put(CTX_TRANSFORMER_IMPL, ti);
167             newContext.put(CTX_STYLESHEET_ROOT, ti.getStylesheet());
168             pushContext(newContext);
169         } catch (EjenException e) {
170             throw e;
171         } catch (Exception JavaDoc e) {
172             throw new EjenException(this, null, e);
173         }
174         finally {
175             if (inputs != null) {
176                 try {
177                     inputs.close();
178                 } catch (Exception JavaDoc e) {}
179                 finally {
180                     inputs = null;
181                 }
182             }
183         }
184         
185     }
186
187     /**
188      * Executes this EjenStylesheetNode (and all child nodes). This method is called
189      * by the process() method in each implementation of the EjenStylesheetNode abstract
190      * class.
191      */

192     public void process() {
193         super.process();
194         try {
195             StylesheetRoot sr = (StylesheetRoot) (getFromContext(CTX_STYLESHEET_ROOT));
196
197             if (sr == null) {
198                 throw new EjenException(this,
199                         "no '" + CTX_STYLESHEET_ROOT + "' in context");
200             }
201             for (Enumeration JavaDoc is = _childNodes.elements(); is.hasMoreElements();) {
202                 EjenChildNode ecn = (EjenChildNode) (is.nextElement());
203                 // sendMessageEvent("Processing " + ecn.toString());
204
String JavaDoc oldMessageIndent = _messageIndent;
205
206                 _messageIndent = LOG_INDENT_STR1 + _messageIndent;
207                 ecn.beforeProcess();
208                 ecn.process();
209                 ecn.afterProcess();
210                 ecn.idle();
211                 _messageIndent = oldMessageIndent;
212             }
213             sr.recompose();
214         } catch (EjenException e) {
215             throw e;
216         } catch (Exception JavaDoc e) {
217             throw new EjenException(this, null, e);
218         }
219     }
220
221     /**
222      * Pops the context that has been pushed by the {@link #beforeProcess()} method.
223      */

224     public void afterProcess() {
225         super.afterProcess();
226         
227         try {
228             popContext();
229         } catch (Exception JavaDoc e) {
230             throw new EjenException(this, null, e);
231         }
232     }
233     
234     private boolean transformInputFile(String JavaDoc file) {
235       
236         boolean retVal = true;
237         DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
238
239         try {
240             File datafile = new File(file);
241             File output = new File(file);
242             
243             DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
244             // factory.setNamespaceAware(false);
245
Document inputDocument = builder.parse(datafile);
246             Document document = builder.parse(datafile);
247             
248             boolean hasImports = true;
249             NodeList list = document.getElementsByTagName("xsl:import");
250             String JavaDoc importHrefValue = "";
251
252             if (list.item(0) != null) {
253                 importHrefValue = ((Element) list.item(0)).getAttribute("href");
254             } else {
255                 hasImports = false;
256             }
257             
258             boolean hasIncludes = true;
259
260             list = document.getElementsByTagName("xsl:include");
261             String JavaDoc includeHrefValue = "";
262
263             if (list.item(0) != null) {
264                 includeHrefValue = ((Element) list.item(0)).getAttribute("href");
265             } else {
266                 hasIncludes = false;
267             }
268             
269             String JavaDoc hrefValue = "";
270
271             if (hasImports) {
272                 hrefValue = importHrefValue;
273             } else if (hasIncludes) {
274                 hrefValue = includeHrefValue;
275             }
276             
277             // if path is OK,leave it unchanged.
278
if ((hasImports || hasIncludes)
279                     && !this.checkFilePath(file, hrefValue)) {
280                 // Use a Transformer for output
281
TransformerFactory JavaDoc tFactory = TransformerFactory.newInstance();
282                 StreamSource JavaDoc stylesource = new StreamSource JavaDoc(new StringReader(stylesheet));
283                 Transformer JavaDoc transformer = tFactory.newTransformer(stylesource);
284    
285                 DOMSource JavaDoc source = new DOMSource JavaDoc(inputDocument);
286                 StreamResult JavaDoc result = new StreamResult JavaDoc(new FileOutputStream(output));
287
288                 transformer.transform(source, result);
289             }
290         } catch (Exception JavaDoc e) {
291             e.printStackTrace();
292             System.out.println("exception in EjenStylesheetNode.transformInputFile() : "
293                     + e.getMessage());
294             retVal = false;
295         }
296         return retVal;
297     }
298     
299     private boolean checkFilePath(String JavaDoc file, String JavaDoc hrefValue) {
300         boolean retVal = false;
301         String JavaDoc relPath = file;
302         String JavaDoc hrefPath = "";
303         // getting main template's path ( path is absolute,so at least one '/' must be in it )
304
int indexOfBackslash = file.lastIndexOf("/");
305
306         relPath = relPath.substring(0, indexOfBackslash + 1);
307         // getting path in href
308
indexOfBackslash = hrefValue.lastIndexOf("/");
309         if (indexOfBackslash != -1) {
310             hrefPath = hrefValue.substring(0, indexOfBackslash + 1);
311         }
312         // comparing href attribute value and relPath
313
if (comparePaths(relPath, hrefPath)) {
314             retVal = true;
315         } else {
316             int startPosition = 0;
317
318             if (indexOfBackslash == -1) {
319                 startPosition = 1;
320             } else {
321                 startPosition = hrefPath.length() + 1;
322             }
323             composeStylesheet(relPath, startPosition);
324         }
325         return retVal;
326     }
327     
328     private boolean comparePaths(String JavaDoc relPath, String JavaDoc hrefPath) {
329         boolean retVal = false;
330
331         if (System.getProperty("path.separator").equals(";")) {
332             retVal = relPath.equalsIgnoreCase(hrefPath);
333         } else {
334             retVal = relPath.equals(hrefPath);
335         }
336         return retVal;
337     }
338     
339     private void composeStylesheet(String JavaDoc relPath, int startPosition) {
340       
341         String JavaDoc stylesheet = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
342                 + "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:gvs=\"org.ejen.ext.GlobalVariables\">"
343                 + "<xsl:output method=\"xml\" indent=\"yes\" encoding=\"UTF-8\"/>"
344                 + "<xsl:template match=\"/\">"
345                 + "<xsl:element name=\"xsl:stylesheet\">"
346                 + "<xsl:attribute name=\"version\">1.0</xsl:attribute>"
347                 + "<xsl:attribute name=\"extension-element-prefixes\">gvs</xsl:attribute>"
348                 + "<xsl:attribute name=\"exclude-result-prefixes\">gvs</xsl:attribute>"
349                 + "<xsl:apply-templates/>" + "</xsl:element>"
350                 + "</xsl:template>" + "<xsl:template match=\"stylesheet/*\">"
351                 + "<xsl:choose>" + "<xsl:when test=\"name() = 'xsl:import'\">"
352                 + "<xsl:call-template name=\"import\"/>" + "</xsl:when>"
353                 + "<xsl:when test=\"name() = 'xsl:include'\">"
354                 + "<xsl:call-template name=\"include\"/>" + "</xsl:when>"
355                 + "<xsl:otherwise>" + "<xsl:copy-of select=\".\"/>"
356                 + "</xsl:otherwise>" + "</xsl:choose>" + "</xsl:template>"
357                 + "<xsl:template name=\"import\">"
358                 + "<xsl:element name=\"xsl:import\">"
359                 + "<xsl:attribute name=\"href\">" + relPath
360                 + "<xsl:value-of select=\"substring(@href," + startPosition
361                 + ")\"/></xsl:attribute>" + "</xsl:element>" + "</xsl:template>"
362                 + "<xsl:template name=\"include\">"
363                 + "<xsl:element name=\"xsl:include\">"
364                 + "<xsl:attribute name=\"href\">" + relPath
365                 + "<xsl:value-of select=\"substring(@href," + startPosition
366                 + ")\"/></xsl:attribute>" + "</xsl:element>" + "</xsl:template>"
367                 + "</xsl:stylesheet>";
368
369         this.stylesheet = stylesheet;
370       
371     }
372 }
373
Popular Tags