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
RevLine 
[466]1package eu.clarin.cmdi.mdservice.action;
2
3import java.io.BufferedInputStream;
[1429]4import java.io.BufferedReader;
[466]5import java.io.ByteArrayInputStream;
6import java.io.ByteArrayOutputStream;
7import java.io.File;
8import java.io.FileInputStream;
9import java.io.IOException;
10import java.io.InputStream;
[1429]11import java.io.InputStreamReader;
[466]12import java.io.OutputStream;
13import java.io.Reader;
14import java.io.StringReader;
[690]15import java.io.StringWriter;
[1429]16import java.io.Writer;
[466]17import java.net.URL;
[879]18import java.util.HashMap;
19import java.util.Iterator;
20import java.util.Map;
21import java.util.Set;
[466]22
[690]23import javax.xml.parsers.DocumentBuilder;
24import javax.xml.parsers.DocumentBuilderFactory;
25import javax.xml.parsers.ParserConfigurationException;
[1429]26//import javax.xml.transform.ErrorListener;
[690]27import javax.xml.transform.OutputKeys;
[466]28import javax.xml.transform.Transformer;
[690]29import javax.xml.transform.TransformerConfigurationException;
[466]30import javax.xml.transform.TransformerException;
31import javax.xml.transform.TransformerFactory;
[690]32import javax.xml.transform.TransformerFactoryConfigurationError;
33import javax.xml.transform.dom.DOMSource;
[466]34import javax.xml.transform.stream.StreamResult;
35import javax.xml.transform.stream.StreamSource;
36
[1429]37//import ognl.IntHashMap.Entry;
[879]38
[1429]39import net.sf.saxon.event.MessageEmitter;
40import net.sf.saxon.event.MessageWarner;
41
[690]42import org.w3c.dom.Document;
43import org.w3c.dom.Element;
44import org.w3c.dom.Node;
45import org.w3c.dom.NodeList;
46
[1429]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
[466]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 ;
[879]66        private HashMap<String,String> params;
[466]67               
[911]68        private MDTransformer singleton;
[466]69        TransformerFactory tfactory ; 
70       
71        public MDTransformer () {               
72                tfactory = TransformerFactory.newInstance();   
73        }
74       
[911]75        /*
[466]76        public static MDTransformer getMDTransformer () {
77                if (singleton == null) {
78                        singleton = new MDTransformer();
79                }
80                return singleton;
81        }
[911]82        */
[466]83       
[501]84        public URL getSrcFile() {
85                return srcFile;
86        }
87
88        public void setSrcFile(URL srcFile) {
89                this.srcFile = srcFile;
90        }
91
[879]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        }
[466]99        /**
100         * get the path to the transform-xsl file from properties, based on the key
101         * @param key
102         * @return
[1488]103         * @throws NoStylesheetException - if no matching entry in properties could be found
[466]104         */
[1488]105        private String getXSLPath (String key) throws NoStylesheetException {           
[466]106                String xslpath = "";
107                String xslfilename= Admin.getConfig().getProperty("xsl." + key);
108               
109                if (xslfilename!=null) {                       
110                        xslpath =  Admin.getConfig().getProperty("scripts.path") + xslfilename;
[1488]111                } else {
112                        throw new NoStylesheetException("No Stylesheet found for format-key: " + key);
113                }
[466]114                Admin.notifyUser("xslfile:" + xslpath);
115                return xslpath;
116        }
117
[1488]118        private StreamSource getXSLStreamSource (String key) throws NoStylesheetException{             
[466]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               
[768]131               
[466]132                streamSource.setSystemId(this.getClass().getClassLoader().getResource(xslPath).toString());
133                return streamSource ;           
134               
135        }
136
[690]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 >
[699]148                        Element root = (Element) doc.createElement("root");
[690]149                        doc.appendChild(root);
150                       
[699]151                        Element child1 = (Element) doc.createElement("col");
152                        child1.setTextContent("Id");
153                        root.appendChild(child1);                       
[690]154                        Element child = (Element) doc.createElement("col");
[699]155                        child.setTextContent("Name");
156                        root.appendChild(child);
[690]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;
[699]184                //return doc.getElementsByTagName("col").item(0);
185                return doc.getDocumentElement();
[690]186        }
187       
[879]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       
[466]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
[1488]211         * @throws NoStylesheetException
[879]212         */
[1488]213        public void transformXML (InputStream in, OutputStream out ) throws TransformerException, IOException, NoStylesheetException {
[879]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 {
[466]215       
[1429]216                        System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
[466]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(
[879]225                                                                        getXSLStreamSource(getTranskey()));
226                SetTransformerParameters(transformer);
[1429]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               
[879]234/*              transformer.setParameter("q", q);
[789]235                transformer.setParameter("lang", lang);
[466]236                transformer.setParameter("format", transkey);
[690]237                transformer.setParameter("cols", cols);
[706]238                if ((startRecord != null) && (maximumRecords != null)) {
239
240                        transformer.setParameter("startRecord", startRecord);
241                        transformer.setParameter("maximumRecords", maximumRecords);
242                }
[849]243                if (repositoryURI != null) {
244
245                        transformer.setParameter("repository_uri", repositoryURI);
246                }
[879]247                */
[706]248                /*       transformer.setParameter("cols", "<col label='id'>Id</col>" +
[699]249                                                                                 "<col label='id'>idno</col>" +
250                                                                                 "<col label='name'>Name</col>" +
251                                                                                 "<col label='title'>Title</col>" +
252                                                                                 "<col label='title'>title</col>"); */
[466]253               
254                if (srcFile!=null) {
[582]255                       
[466]256                        File f = new File(srcFile.getPath());
[582]257                           
[466]258                        //Admin.notifyUser("src:" + srcFile.getFile());
259                        //Admin.notifyUser("fpath:" + f.getAbsolutePath());
[501]260                        String root_uri =  srcFile.toString();
[466]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                        } 
[849]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                       
[466]273                        Admin.notifyUser("root_uri:" +  root_uri );
[795]274                        Admin.notifyUser("xsrcfile:" +  xsrcfile );
[1431]275                       
[466]276                        transformer.setParameter("root_uri", root_uri );
277                        transformer.setParameter("src_file", xsrcfile);
[501]278                } else {
279                        Admin.notifyUser("transformXML(): srcFile not set!!");                         
[466]280                }
[501]281                //
[466]282                StreamSource src =new StreamSource();                   
283                src.setInputStream(in);
284                // Transform the source XML to out-stream
285                transformer.transform(src, stream );
[1429]286               
287                // Write <xsl:message>
288                writeXslMessages(w);
289                ///Admin.notifyUser(w.getBuffer().toString());         
[466]290            }
291       
[1429]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        }
[466]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
[1488]316         * @throws NoStylesheetException
[466]317         */
[1488]318        public InputStream transformXML ( InputStream xmlStream) throws IOException, InterruptedException, TransformerException, NoStylesheetException {
[879]319        //public InputStream transformXML ( InputStream xmlStream, String transkey, String cols, String startRecord, String maximumRecords, String lang, String q, String repositoryURI) throws IOException, InterruptedException, TransformerException {
[690]320               
321                ByteArrayOutputStream out = new ByteArrayOutputStream();
[879]322                transformXML(xmlStream, out);
323                //transformXML(xmlStream, transkey, cols, startRecord, maximumRecords, lang, q, repositoryURI, out);           
[690]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         */
[879]338        /*
[466]339        public InputStream transformXML ( InputStream xmlStream, String transkey) throws IOException, InterruptedException, TransformerException {
340               
341                ByteArrayOutputStream out = new ByteArrayOutputStream();
[849]342                transformXML(xmlStream, transkey, "", "", "","","", "", out);           
[466]343            InputStream transformedStream = new ByteArrayInputStream(out.toByteArray());
344            //Admin.notifyUser("transformedStream:" + transformedStream.toString());
345            return transformedStream;
346        }
[879]347*/
[466]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
[1488]355         * @throws NoStylesheetException
[466]356         */
[1488]357        public InputStream transformXML (URL xmlFile ) throws IOException, InterruptedException, TransformerException, NoStylesheetException {
[879]358        //public InputStream transformXML (URL xmlFile, String transkey ) throws IOException, InterruptedException, TransformerException {
[466]359                srcFile= xmlFile;
360                InputStream  xmlStream =
361             new BufferedInputStream(new FileInputStream(xmlFile.getPath()));
362           
[879]363                return transformXML ( xmlStream); 
[466]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
[1488]373         * @throws NoStylesheetException
[1429]374         * @throws IOException
[466]375         */
[1488]376        public String transformXML (String xml) throws NoStylesheetException {
[879]377        //public String transformXML (String xml, String transkey ) {
[466]378                String result="";
379                try {
380                // Create a transform factory instance.
381                        System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
[1429]382                        //System.setProperty("javax.xml.transform.TransformerFactory", "com.icl.saxon.TransformerFactoryImpl");
[466]383                TransformerFactory tfactory = TransformerFactory.newInstance();
384                OutputStream os = new ByteArrayOutputStream();
385                StreamResult stream = new StreamResult(os);
386                // Create a transformer for the stylesheet.
[500]387                Transformer transformer = tfactory.newTransformer(
[879]388                                                getXSLStreamSource(getTranskey()));
[500]389/* instead of:
[466]390                InputStream  xslIS       =
391                    new BufferedInputStream(new FileInputStream(getXSLPath(transkey)));
392               
393                Transformer transformer =
394                    tfactory.newTransformer(new StreamSource(xslIS));
[500]395                    */
[1429]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());
[466]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")));
[1429]409             // Write <xsl:message>
410                writeXslMessages(w);
411                 
[466]412                result = os.toString(); 
413               
414                        } catch (TransformerException e) {
415                                e.printStackTrace();
416                        }
417                       
418                        return result;
419        }
420
[690]421       
[879]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        }
[466]430}
Note: See TracBrowser for help on using the repository browser.