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