001/****************************************************************************/
002/* Copyright/Copyleft: 
003 * 
004 * For this source the LGPL Lesser General Public License, 
005 * published by the Free Software Foundation is valid.
006 * It means:
007 * 1) You can use this source without any restriction for any desired purpose.
008 * 2) You can redistribute copies of this source to everybody.
009 * 3) Every user of this source, also the user of redistribute copies 
010 *    with or without payment, must accept this license for further using.
011 * 4) But the LPGL ist not appropriate for a whole software product,
012 *    if this source is only a part of them. It means, the user 
013 *    must publish this part of source,
014 *    but don't need to publish the whole source of the own product.
015 * 5) You can study and modify (improve) this source 
016 *    for own using or for redistribution, but you have to license the
017 *    modified sources likewise under this LGPL Lesser General Public License.
018 *    You mustn't delete this Copyright/Copyleft inscription in this source file.    
019 *
020 * @author www.vishia.de/Java
021 * @version 2006-06-15  (year-month-day)
022 * list of changes: 
023 * 2006-05-00: www.vishia.de creation
024 *
025 ****************************************************************************/
026
027package org.vishia.xml;
028
029import org.jdom.*;
030
031import java.io.File;
032import java.io.FileNotFoundException;
033import java.util.*;
034//import java.io.*;
035
036import org.vishia.mainCmd.*;
037import org.vishia.xmlSimple.XmlException;
038
039/** Class to transform XML files with XSLT. 
040 *  This class is also used inside the vishia.xslt.Xslt XSL Translator. 
041 *  See <a href="Xslt.html">Xslt</a> for Description of command line
042 *  or argument string invocation and Description of features of the translator.
043 */
044public class XslTransformer
045{
046  /** contact to the streamoriented output*/
047  private final Report main;
048  //Document docu;
049  private Element xmlRoot;
050
051  /** Class holding one element inside the List "listFileIn" of the transform-method.
052   * 
053   * 
054   */
055  public static class FileTypeIn
056  { public static final int mReplaceWhiteSpaceWith1Space = 0x0001;
057    public static final int mExpandAsciiFormating        = 0x0002;
058    private final String sName;
059    /** Mode of preprocessing inputfile, see m... */
060    private final int mode; 
061
062    private final File fileIn;
063    
064    public FileTypeIn(String sFileIn, int mode)
065    { sName = sFileIn;
066      fileIn = new File(sName);
067      this.mode = mode;
068    }
069    
070    public Element readXmlFile()
071    throws XsltException, FileNotFoundException
072    {
073      Element xmlInput = null;
074      try
075      { if( (mode & mReplaceWhiteSpaceWith1Space ) != 0)
076        { xmlInput = XmlExtensions.readXmlFileTrimWhiteSpace(fileIn);
077        }
078        else
079        { xmlInput = XmlExtensions.readXmlFile(fileIn);
080        }
081      }
082      catch(XmlException exception){ throw new XsltException(exception.getMessage(), Report.exitWithFileProblems, exception);}
083      return xmlInput;
084    }
085    
086    public String getAbsolutePath()
087    { return fileIn.getAbsolutePath();
088    }
089  }
090
091  
092  
093  
094  
095  /** The instance should known a main interface 
096   * 
097   * @param main The instance to report something.
098   */
099  XslTransformer(Report main)
100  { this.main = main;
101  }
102
103
104  /** Transforms some input XML-files via XSL to one output XML-file.
105    @param listFileIn List of input file pathes, given as Instances of FileTypeIn.
106    @param fileXsl translater xsl file
107    @param sFileOut Path of the output file
108    @param mode Mode of conversion, text or xml
109    @param fileInputOnError may be null, if not null and any error occurs, the input tree
110           is written to this file to enable check it by user.
111    @throws XsltException if any error. The exception contains a string from this
112            method with pathes, the exitErrorLevel and the original exception.
113   * @throws FileNotFoundException if the output file cannot be written or replaced.
114   * @throws XmlException 
115  */
116  public void transform
117  ( List<FileTypeIn> listFileIn
118  , File fileXsl
119  , File  fileOut
120  , XmlExtensions.XmlMode mode
121  , File fileInputOnError
122  )
123  throws XsltException, FileNotFoundException, XmlException
124  { //boolean bOk = true;  //successfull work
125
126    String sPath = fileOut.getAbsolutePath();
127    xmlRoot = new Element("root");
128    Iterator<FileTypeIn> iterFileIn = listFileIn.iterator();
129    while(iterFileIn.hasNext())
130    { //add one xml-tree from the given input file to /root
131      FileTypeIn input = (FileTypeIn)(iterFileIn.next());
132      String sFileIn = input.sName;
133      main.reportln(Report.info, "reading " + sFileIn);
134      Element xmlInput = input.readXmlFile();
135      xmlInput.detach();
136      xmlRoot.addContent(xmlInput);
137      main.report(Report.info," ...done.");
138    }
139    try{ XmlExtensions.writeXmlDirect(xmlRoot, new File(sPath + ".i.xml"), "ISO-8859-1"); }
140    catch(XmlException exception){ main.report("test", exception); }
141    if(mode.isText())
142    { //conversion produce a text
143      //catch(IOException exception ){ main.exit("ERROR writing" + sName + "\n  " + exception.getMessage(), Report.exitWithFileProblems, exception);}
144    }
145    else if(mode.isXml())
146    { //conversion produce a xml tree or xhtml tree:
147      Element xmlOut = null;
148      Exception transformException = null;
149      main.reportln(Report.info, "translating via " + fileXsl.getAbsolutePath());
150      try{ xmlOut = XmlExtensions.xslTransformXml(xmlRoot, fileXsl);}
151      catch(XmlException exception)
152      { //System.out.println("...error transformation!");
153        transformException = exception;
154      }
155      if(transformException != null)
156      { //try to write the input tree to the output file to report the input:
157        Element xmlError = new Element("TheInputTreeOnError");
158        xmlRoot.detach();
159        xmlError.addContent(xmlRoot);
160        if(fileInputOnError != null)
161        { try{ XmlExtensions.writeXmlFile(xmlError, fileInputOnError, mode); }
162                catch(XmlException exception)
163                { throw new XsltException
164                        ( "ERROR translating and writing:" 
165                  + fileOut.getAbsolutePath() 
166                  + "\n  " + exception.getMessage()
167                  + transformException.getMessage()
168                  , Report.exitWithFileProblems, exception);
169                }
170        }
171              throw new XsltException("ERROR translating with:" + fileXsl.getAbsolutePath() + "\n  " + transformException.getMessage(), Report.exitWithFileProblems, transformException);
172      }
173      main.report(Report.info," ...done.");
174      main.reportln(Report.info, "writing " + sPath);
175
176            try{ XmlExtensions.writeXmlDirect(xmlOut, new File(sPath + ".a.xml"), "ISO-8859-1"); }
177            catch(XmlException exception){ main.report("test-a", exception); }
178      
179      //ConverterWikistyleTextToXml toWikistyle = new ConverterWikistyleTextToXml(main); 
180      //toWikistyle.testXmlTreeAndConvert(xmlOut);
181
182            try{ XmlExtensions.writeXmlDirect(xmlRoot, new File(sPath + ".b.xml"), "ISO-8859-1"); }
183            catch(XmlException exception){ main.report("test-b", exception); }
184      
185
186      if(mode.isIndent())
187      { xmlOut = XmlExtensions.beautificationBewareTextContent(xmlOut);
188      }
189      try{ XmlExtensions.writeXmlFile(xmlOut, fileOut, mode); }
190      catch(XmlException exception)
191      { throw new XsltException("ERROR writing:" + fileOut.getAbsolutePath() + "\n  " + exception.getMessage(), Report.exitWithFileProblems, exception);
192      }
193      main.report(Report.info, " ...done.");
194    }
195    else
196    { throw new XsltException("failed convert mode", Report.exitWithArgumentError);
197    }
198  }
199
200  
201  
202  
203}
204
205
206
207
208
209
210