source: MDService2/trunk/MDService2/src/eu/clarin/cmdi/mdservice/action/MDTransformer.java @ 1488

Last change on this file since 1488 was 1488, checked in by vronk, 13 years ago

output - method, DOCTYPE, encoding issues (trying to unify for xhtml (but not over all xsls yet); test-suite update

File size: 15.2 KB
Line 
1package eu.clarin.cmdi.mdservice.action;
2
3import java.io.BufferedInputStream;
4import java.io.BufferedReader;
5import java.io.ByteArrayInputStream;
6import java.io.ByteArrayOutputStream;
7import java.io.File;
8import java.io.FileInputStream;
9import java.io.IOException;
10import java.io.InputStream;
11import java.io.InputStreamReader;
12import java.io.OutputStream;
13import java.io.Reader;
14import java.io.StringReader;
15import java.io.StringWriter;
16import java.io.Writer;
17import java.net.URL;
18import java.util.HashMap;
19import java.util.Iterator;
20import java.util.Map;
21import java.util.Set;
22
23import javax.xml.parsers.DocumentBuilder;
24import javax.xml.parsers.DocumentBuilderFactory;
25import javax.xml.parsers.ParserConfigurationException;
26//import javax.xml.transform.ErrorListener;
27import javax.xml.transform.OutputKeys;
28import javax.xml.transform.Transformer;
29import javax.xml.transform.TransformerConfigurationException;
30import javax.xml.transform.TransformerException;
31import javax.xml.transform.TransformerFactory;
32import javax.xml.transform.TransformerFactoryConfigurationError;
33import javax.xml.transform.dom.DOMSource;
34import javax.xml.transform.stream.StreamResult;
35import javax.xml.transform.stream.StreamSource;
36
37//import ognl.IntHashMap.Entry;
38
39import net.sf.saxon.event.MessageEmitter;
40import net.sf.saxon.event.MessageWarner;
41
42import org.w3c.dom.Document;
43import org.w3c.dom.Element;
44import org.w3c.dom.Node;
45import org.w3c.dom.NodeList;
46
47//import com.icl.saxon.*;
48//import com.icl.saxon.FeatureKeys;
49//import com.icl.saxon.Loader;
50//import com.icl.saxon.output.Emitter;
51
52
53/**
54 * Helper class, encapsulating the xsl-transformations handling
55 * the contract is, that the requester passes a key, which can be resolved to a xsl-script (momentary mapped in properties: Admin.getConfig())
56 * Bad things happen, if the key or the appropriate xsl-file do not exist
57 *   
58 *
59 * @author vronk
60 *
61 */
62
63public class MDTransformer {
64
65        private URL srcFile ;
66        private HashMap<String,String> params;
67               
68        private MDTransformer singleton;
69        TransformerFactory tfactory ; 
70       
71        public MDTransformer () {               
72                tfactory = TransformerFactory.newInstance();   
73        }
74       
75        /*
76        public static MDTransformer getMDTransformer () {
77                if (singleton == null) {
78                        singleton = new MDTransformer();
79                }
80                return singleton;
81        }
82        */
83       
84        public URL getSrcFile() {
85                return srcFile;
86        }
87
88        public void setSrcFile(URL srcFile) {
89                this.srcFile = srcFile;
90        }
91
92        public void setParams(HashMap<String,String> params){
93                this.params = params;
94        }
95       
96        public HashMap<String,String> getParams(){
97                return this.params;
98        }
99        /**
100         * get the path to the transform-xsl file from properties, based on the key
101         * @param key
102         * @return
103         * @throws NoStylesheetException - if no matching entry in properties could be found
104         */
105        private String getXSLPath (String key) throws NoStylesheetException {           
106                String xslpath = "";
107                String xslfilename= Admin.getConfig().getProperty("xsl." + key);
108               
109                if (xslfilename!=null) {                       
110                        xslpath =  Admin.getConfig().getProperty("scripts.path") + xslfilename;
111                } else {
112                        throw new NoStylesheetException("No Stylesheet found for format-key: " + key);
113                }
114                Admin.notifyUser("xslfile:" + xslpath);
115                return xslpath;
116        }
117
118        private StreamSource getXSLStreamSource (String key) throws NoStylesheetException{             
119               
120                InputStream xslstream;
121                                       
122                //URL myURL = new URL (getXSLPath(key));
123                //xslstream = myURL.openStream();
124                String xslPath = getXSLPath(key);
125                xslstream = this.getClass().getClassLoader().getResourceAsStream(xslPath);
126                StreamSource streamSource = new StreamSource(xslstream);
127
128                //Admin.notifyUser(this.getClass().getClassLoader().getResource(xslPath).toString());
129                //Admin.notifyUser(this.getClass().getClassLoader().getResource(xslPath).getPath());
130               
131               
132                streamSource.setSystemId(this.getClass().getClassLoader().getResource(xslPath).toString());
133                return streamSource ;           
134               
135        }
136
137        public Object getCols() throws TransformerConfigurationException, TransformerFactoryConfigurationError{
138               
139                String xmlString = null;
140                // create new document
141                Document doc = null;
142                DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
143        DocumentBuilder docBuilder;
144                try {
145                        docBuilder = docFactory.newDocumentBuilder();
146                        doc = docBuilder.newDocument();
147                        // append root tag <col >
148                        Element root = (Element) doc.createElement("root");
149                        doc.appendChild(root);
150                       
151                        Element child1 = (Element) doc.createElement("col");
152                        child1.setTextContent("Id");
153                        root.appendChild(child1);                       
154                        Element child = (Element) doc.createElement("col");
155                        child.setTextContent("Name");
156                        root.appendChild(child);
157                        //Element child = doc.createElement("col");
158                        //child.setNodeValue("Id");
159                       
160                       
161                        Transformer transformer = TransformerFactory.newInstance().newTransformer();
162                        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
163
164                        //initialize StreamResult with File object to save to file
165                        StreamResult result = new StreamResult(new StringWriter());
166                        DOMSource source = new DOMSource(doc);
167                        try {
168                                transformer.transform(source, result);
169                                xmlString = result.getWriter().toString();
170                               
171                                Admin.notifyUser(xmlString);
172                        } catch (TransformerException e) {
173                                // TODO Auto-generated catch block
174                                e.printStackTrace();
175                        }
176
177                       
178
179                } catch (ParserConfigurationException e) {
180                        // TODO Auto-generated catch block
181                        e.printStackTrace();
182                }
183                //return xmlString;
184                //return doc.getElementsByTagName("col").item(0);
185                return doc.getDocumentElement();
186        }
187       
188        public String getTranskey(){
189                return params.get("format");
190        }
191       
192        public void SetTransformerParameters(Transformer transformer){
193               
194                Set<Map.Entry<String,String>> set = params.entrySet();
195                Iterator<Map.Entry<String,String>> i = set.iterator();
196
197            while(i.hasNext()){
198              Map.Entry<String,String> e = (Map.Entry<String,String>)i.next();
199              transformer.setParameter((String)e.getKey(), (String)e.getValue());
200            }
201        }
202       
203        /**
204         * The main method for transforming, applies the appropriate (based on the transkey) stylesheet on the xml-stream
205         * and writes the result into the output stream.   
206         * @param in InpuStream with xml 
207         * @param transkey this defines the stylesheet to use and is also passed to the stylesheet as "format"-parameter
208         * @param out the stream to write the output to
209         * @throws TransformerException
210         * @throws IOException
211         * @throws NoStylesheetException
212         */
213        public void transformXML (InputStream in, OutputStream out ) throws TransformerException, IOException, NoStylesheetException {
214        //public void transformXML (InputStream in, String transkey, String cols, String startRecord, String maximumRecords, String lang, String q, String repositoryURI, OutputStream out ) throws TransformerException, IOException {
215       
216                        System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
217                // Create a transform factory instance.
218                TransformerFactory tfactory = TransformerFactory.newInstance();
219                //OutputStream os = new ByteArrayOutputStream();
220                StreamResult stream = new StreamResult(out);
221               
222                // Create a transformer for the stylesheet.
223                        //String xslpath = getXSLPath(transkey);               
224                Transformer transformer = tfactory.newTransformer(
225                                                                        getXSLStreamSource(getTranskey()));
226                SetTransformerParameters(transformer);
227               
228                //MessageWarner gg = new net.sf.saxon.event.MessageWarner();
229                MessageEmitter me = new net.sf.saxon.event.MessageEmitter();
230                StringWriter w = new StringWriter();
231                me.setWriter(w);
232               ((net.sf.saxon.Controller)transformer).setMessageEmitter(me);//new net.sf.saxon.event.MessageWarner());
233               
234/*              transformer.setParameter("q", q);
235                transformer.setParameter("lang", lang);
236                transformer.setParameter("format", transkey);
237                transformer.setParameter("cols", cols);
238                if ((startRecord != null) && (maximumRecords != null)) {
239
240                        transformer.setParameter("startRecord", startRecord);
241                        transformer.setParameter("maximumRecords", maximumRecords);
242                }
243                if (repositoryURI != null) {
244
245                        transformer.setParameter("repository_uri", repositoryURI);
246                }
247                */
248                /*       transformer.setParameter("cols", "<col label='id'>Id</col>" +
249                                                                                 "<col label='id'>idno</col>" +
250                                                                                 "<col label='name'>Name</col>" +
251                                                                                 "<col label='title'>Title</col>" +
252                                                                                 "<col label='title'>title</col>"); */
253               
254                if (srcFile!=null) {
255                       
256                        File f = new File(srcFile.getPath());
257                           
258                        //Admin.notifyUser("src:" + srcFile.getFile());
259                        //Admin.notifyUser("fpath:" + f.getAbsolutePath());
260                        String root_uri =  srcFile.toString();
261                        String xsrcfile =  srcFile.getFile();
262                        if  (srcFile.getProtocol().equals("file")) {
263                                root_uri = "file:///" + f.getParent().replace('\\', '/');
264                                xsrcfile = "file:///" + f.getPath().replace('\\', '/');
265                        } 
266                        // TODO repository-path -removed, bad formating
267                        String[] xsrcfiles = xsrcfile.split("&repository=");
268                        String[] root_uris = root_uri.split("&repository=");
269                        xsrcfile = xsrcfiles[0];
270                        root_uri = root_uris[0];
271                        ///
272                       
273                        Admin.notifyUser("root_uri:" +  root_uri );
274                        Admin.notifyUser("xsrcfile:" +  xsrcfile );
275                       
276                        transformer.setParameter("root_uri", root_uri );
277                        transformer.setParameter("src_file", xsrcfile);
278                } else {
279                        Admin.notifyUser("transformXML(): srcFile not set!!");                         
280                }
281                //
282                StreamSource src =new StreamSource();                   
283                src.setInputStream(in);
284                // Transform the source XML to out-stream
285                transformer.transform(src, stream );
286               
287                // Write <xsl:message>
288                writeXslMessages(w);
289                ///Admin.notifyUser(w.getBuffer().toString());         
290            }
291       
292        private void writeXslMessages(StringWriter w){
293       
294        byte[] bytes = w.getBuffer().toString().getBytes();
295        InputStream is =  new ByteArrayInputStream(bytes);
296        BufferedReader br = new BufferedReader(new InputStreamReader(is));
297        String s;
298                try {
299                        while ((s = br.readLine()) != null){
300                        Admin.notifyUser(s);
301                }
302                } catch (IOException e) {
303                        // TODO Auto-generated catch block
304                        e.printStackTrace();
305                }
306
307        }
308        /**
309         * just a wrapper for the main method translating the output-stream into a input-stream (expected by the Controller-Actions to return as response)
310         * @param xmlStream the source xml stream
311         * @param transkey
312         * @return result-stream (converted to InputStream)
313         * @throws IOException
314         * @throws InterruptedException
315         * @throws TransformerException
316         * @throws NoStylesheetException
317         */
318        public InputStream transformXML ( InputStream xmlStream) throws IOException, InterruptedException, TransformerException, NoStylesheetException {
319        //public InputStream transformXML ( InputStream xmlStream, String transkey, String cols, String startRecord, String maximumRecords, String lang, String q, String repositoryURI) throws IOException, InterruptedException, TransformerException {
320               
321                ByteArrayOutputStream out = new ByteArrayOutputStream();
322                transformXML(xmlStream, out);
323                //transformXML(xmlStream, transkey, cols, startRecord, maximumRecords, lang, q, repositoryURI, out);           
324            InputStream transformedStream = new ByteArrayInputStream(out.toByteArray());
325            //Admin.notifyUser("transformedStream:" + transformedStream.toString());
326            return transformedStream;
327        }
328       
329        /**
330         * just a wrapper for the main method translating the output-stream into a input-stream (expected by the Controller-Actions to return as response)
331         * @param xmlStream the source xml stream
332         * @param transkey
333         * @return result-stream (converted to InputStream)
334         * @throws IOException
335         * @throws InterruptedException
336         * @throws TransformerException
337         */
338        /*
339        public InputStream transformXML ( InputStream xmlStream, String transkey) throws IOException, InterruptedException, TransformerException {
340               
341                ByteArrayOutputStream out = new ByteArrayOutputStream();
342                transformXML(xmlStream, transkey, "", "", "","","", "", out);           
343            InputStream transformedStream = new ByteArrayInputStream(out.toByteArray());
344            //Admin.notifyUser("transformedStream:" + transformedStream.toString());
345            return transformedStream;
346        }
347*/
348        /**
349         * another wrapper for the main method allowing to directly pass a URL to the source-xml   
350         * @param xmlFile URL of the source-file   
351         * @param transkey
352         * @return the result-stream (already converted to an InputStream)
353         * @throws TransformerException
354         * @throws IOException
355         * @throws NoStylesheetException
356         */
357        public InputStream transformXML (URL xmlFile ) throws IOException, InterruptedException, TransformerException, NoStylesheetException {
358        //public InputStream transformXML (URL xmlFile, String transkey ) throws IOException, InterruptedException, TransformerException {
359                srcFile= xmlFile;
360                InputStream  xmlStream =
361             new BufferedInputStream(new FileInputStream(xmlFile.getPath()));
362           
363                return transformXML ( xmlStream); 
364        }
365
366
367        /**
368         * this is for xml present as string.
369         * if xml in a file or a stream, use the other methods
370         * @param xml xml as string
371         * @param transkey
372         * @return
373         * @throws NoStylesheetException
374         * @throws IOException
375         */
376        public String transformXML (String xml) throws NoStylesheetException {
377        //public String transformXML (String xml, String transkey ) {
378                String result="";
379                try {
380                // Create a transform factory instance.
381                        System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
382                        //System.setProperty("javax.xml.transform.TransformerFactory", "com.icl.saxon.TransformerFactoryImpl");
383                TransformerFactory tfactory = TransformerFactory.newInstance();
384                OutputStream os = new ByteArrayOutputStream();
385                StreamResult stream = new StreamResult(os);
386                // Create a transformer for the stylesheet.
387                Transformer transformer = tfactory.newTransformer(
388                                                getXSLStreamSource(getTranskey()));
389/* instead of:
390                InputStream  xslIS       =
391                    new BufferedInputStream(new FileInputStream(getXSLPath(transkey)));
392               
393                Transformer transformer =
394                    tfactory.newTransformer(new StreamSource(xslIS));
395                    */
396                ////////////////////
397                MessageEmitter me = new net.sf.saxon.event.MessageEmitter();
398                StringWriter w = new StringWriter();
399                me.setWriter(w);
400                ((net.sf.saxon.Controller)transformer).setMessageEmitter(me);//new net.sf.saxon.event.MessageWarner());
401
402                // Transform the source XML to System.out.
403                StreamSource src =new StreamSource();       
404                Reader reader  = new StringReader(xml);
405                src.setReader(reader);
406               
407                transformer.transform(src, stream );
408                                    //  new StreamResult(new File("Simple2.out")));
409             // Write <xsl:message>
410                writeXslMessages(w);
411                 
412                result = os.toString(); 
413               
414                        } catch (TransformerException e) {
415                                e.printStackTrace();
416                        }
417                       
418                        return result;
419        }
420
421       
422        public static HashMap<String,String> createParamsMap(String transkey){
423                HashMap<String,String> hm = new HashMap<String,String>();
424               
425            if (transkey != null){
426                        hm.put("format", transkey);
427            }
428            return hm;
429        }
430}
Note: See TracBrowser for help on using the repository browser.