/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2006, by :
* Corporate:
* EADS Astrium SAS
* Individual:
* Claude Cazenave
*
* $Id: XmlFormater.java,v 1.1 2006/11/03 07:51:28 booba_skaya Exp $
*
* Changes
* -------
*
*/
package simtools.util;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
/**
* Class XmlFormater
* XmlFormater: a tool to indent xml files.
*/
public class XmlFormater {
/**(<b>String</b>) INDENT_STRING: The string used to indent.*/
private static final String INDENT_STRING = "\t";
/**(<b>char</b>) OPENING_TAG_CHAR: the char that indicates a tag opening.*/
private static final char OPENING_TAG_CHAR = '<';
/**(<b>char</b>) CLOSING_TAG_CHAR: The tag that indicate a tag closing.*/
private static final char CLOSING_TAG_CHAR = '>';
/**(<b>String</b>) USAGE: The usage to be displayed.*/
private static final String USAGE= "Usage: XmlFormater [inputFile] [outputFile]?\n" +
"Summary: Indent xml input file.\n" +
"If output file is indicated write result in it.\n" +
"else write to stdout";
/**(<b>FileInputStream</b>) fis: The input stream to read from.*/
private FileInputStream fis;
/**(<b>PrintStream</b>) out: The output stream to write the result.*/
private PrintStream out;
/**(<b>int</b>) indentLevel: The current indent level.*/
private int indentLevel;
/**
* Method main
* <br><b>Summary:</b><br>
* This method permits to format an xml file.
* This method read the given file, and print the result.<br/>
* -On stdout
* -or in ouput file if precised.
* @param args inputFile [outputFile]?
*/
public static void main(String[] args) throws IOException {
if (args.length == 1 || args.length == 2) {
XmlFormater formater = new XmlFormater();
if(args.length == 1){
//Print result on std out.
formater.indentFile(args[0]);
}else if(args.length == 2){
//Print result in result file.
formater.indentFile(args[0], args[1]);
System.out.println("Format done.");
}
}else{
//Print usage if arguments are not valid
System.out.println(USAGE);
}
}
/**
* Method indentFile
* <br><b>Summary:</b><br>
* read a tagged file and write formated output on stdout.
* @param xmlFile
* @throws IOException
*/
private void indentFile(String xmlFile) throws IOException {
//Just have to open the file.
fis = new FileInputStream(xmlFile);
//Use System.out as output stream.
out = System.out;
indentLevel = 0;
parse();
}
/**
* Method indentFile
* <br><b>Summary:</b><br>
* read a tagged file and write formated output in given output file.
* @param inputFile The input file to indent.
* @param ouputFile The output file to write the result.
* @throws IOException
*/
private void indentFile(String inputFile, String ouputFile) throws IOException {
//Just have to open the file.
fis = new FileInputStream(inputFile);
out = new PrintStream(new FileOutputStream(ouputFile));
indentLevel = 0;
parse();
}
/**
* Method parse
* <br><b>Summary:</b><br>
* parse the input stream and write the indented stream in the output printStream
*/
private void parse() throws IOException {
//The current char.
int c = fis.read();
String currentString = "";
while (c != -1) {
if (c == OPENING_TAG_CHAR) {
//We have to parse a TAG.
String tag = OPENING_TAG_CHAR + getNextTag() + CLOSING_TAG_CHAR;
if(!currentString.equals("")){
printString(currentString +"\n");
}
currentString = "";
//Check tag format.
if (tag.startsWith("</")) {
//It is a closing tag.
//return to upper level
indentLevel--;
printString(tag+"\n");
}else if(tag.endsWith("/>")){
//nothing to do with the level.
printString(tag+"\n");
}else if(tag.endsWith(">")){
printString(tag+"\n");
//Go down in level.
indentLevel++;
}
}else{
currentString += (char) c;
}
c = fis.read();
}
}
private void printString(String currentString) {
//construct message to print.
String message = "";
for (int i = 0; i < indentLevel; i++) {
message += INDENT_STRING;
}
message += currentString;
out.print(message);
out.flush();
}
/**
* Method getNextTag
* <br><b>Summary:</b><br>
* Retrieve the chars from input stream till found the end of tag char.
* Return the whole tag, without closing tag.
* @return <b>(String)</b> the whole tag, without opening and closing tag.
* @throws IOException
*/
private String getNextTag() throws IOException {
//Read the input till found an end of tag.
String result = "";
//The current char.
int c = fis.read();
while (c != -1 && c != CLOSING_TAG_CHAR) {
result += "" + (char) c;
c = fis.read();
}
return result;
}
}