package aword;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import kameleon.document.Array;
import kameleon.document.Cell;
import kameleon.document.CellHeader;
import kameleon.document.Document;
import kameleon.document.ElementPropertiesDefaultNames;
import kameleon.document.Paragraph;
import kameleon.document.Paragraphs;
import kameleon.document.Row;
import kameleon.document.Text;
import kameleon.document.TextParagraph;
import kameleon.document.TextParagraphElement;
import kameleon.document.Title;
import kameleon.exception.InvalidIndexException;
import kameleon.exception.InvalidPropertyException;
import kameleon.exception.KameleonException;
import kameleon.plugin.Analyzer;
import kameleon.plugin.SupportedOptions;
import kameleon.util.IODocument;
import kameleon.util.IOFile;
import aword.analyze.LexicalAnalyzer;
import aword.analyze.SyntaxAnalyzer;
/**
* Main class.
*
* <p>Launches the analyzer for the given file and writes the result to the given file.
*
* <p>Proper usage requires three command line arguments :
* <pre> -a <analyzed file> <result file></pre>
*
* @author Dervin Cyrielle, Schnell Michaël
* @version 1.0
*/
public class Main extends Analyzer {
/**
* Main function.
*
* @param args
* command line arguments
*
* @see Main#checkArgs(String[])
*/
public static void main(String[] args) {
// new Main(args) ;
try {
new Main().copyPicture(
"C:\\Users\\Kay\\Desktop\\.kameleon\\.resources") ;
} catch (KameleonException e) {
// e.printStackTrace();
}
}// main
/**
*
*/
public Main() {
super() ;
}
/**
* Sole constructor.
*
* @param args
* command line arguments
*
* @see Main#checkArgs(String[])
*/
public Main(String[] args) {
this() ;
try {
/* Check and retrieve arguments */
Main.checkArgs(args) ;
String analyzedFile = args[1] ;
String resultFile = args[2] ;
/* Analyze file */
System.out.printf("~~ Word Analyzer ~~\n") ;
System.out.printf("Analyzing file '%s'.\n",
analyzedFile) ;
Document d = Main.analyzeFile(analyzedFile) ;
/* Correct analyze flaws */
Main.refactorTitles(d) ;
Main.refactorParagraphs(d) ;
Main.refactorTables(d) ;
/* Save result */
System.out.print("Saving result ....\n") ;
IODocument.writeToFile(d, resultFile) ;
System.out.print("File successfully analyzed.\n") ;
} catch (KameleonException e) {
System.exit(1) ;
}// try
}// Main(String[])
/**
* Checks the given command line arguments.
*
* <p>The program needs 3 arguments to run properly :
* <ol>
* <li>{@code -a} : analyze the given file
* <li>{@code <analyzed file>} : path of the file analyzed by the program
* <li>{@code <result file>} : path of the target file for the result
*
* @param args
* command line arguments
*
* @throws KameleonException
* If the number of arugments is incorrect
*/
protected static void checkArgs(String[] args) throws KameleonException {
int nExpectedParamters = 4 ;
if (args.length != nExpectedParamters) {
throw new KameleonException(//TODO Translate error message
String.format("Nombre d'arguments incorrect, %d trouves, %d attendus.\n",
args.length, nExpectedParamters)) ;
}// if
}// checkArgs(String[])
/**
* Analyzes the given file.
*
* @param analyzedFile
* path of the analyzed file
*
* @return instance of {@code Document} resulting from the analyzed file
*
* @throws KameleonException
* if an error occurred while analyzing the file
*/
protected static Document analyzeFile(String analyzedFile)
throws KameleonException {
try {
SyntaxAnalyzer a = new SyntaxAnalyzer(
new LexicalAnalyzer(new InputStreamReader(
new FileInputStream(analyzedFile), "UTF-8"))) ;
return (Document) a.parse().value ;
} catch (FileNotFoundException e) {
//TODO Ajouter notre exception
throw new KameleonException(e.getMessage()) ;
} catch (Exception e) {
//TODO Ajouter notre exception
throw new KameleonException(e.getMessage()) ;
}// try
}// analyzeFile(String)
protected static void refactorTitles(Document d)
throws KameleonException {
int index = 0 ;
HashMap<Integer, Paragraph> replacement = new HashMap<Integer, Paragraph>() ;
for(Paragraph p : d) {
if (p instanceof TextParagraph) {
TextParagraph tp = (TextParagraph) p ;
if (p.isProperty(ElementPropertiesDefaultNames.STYLE)) {
String style = (String) p.getProperty(ElementPropertiesDefaultNames.STYLE) ;
int titleLevel = Main.getTitleLevel(style) ;
if (titleLevel > 0) {
Title title = new Title() ;
title.setProperty(ElementPropertiesDefaultNames.TEXT_ALIGNMENT,
title.getProperty(ElementPropertiesDefaultNames.TEXT_ALIGNMENT)) ;
title.setProperty(ElementPropertiesDefaultNames.TITLE_LEVEL,
titleLevel) ;
title.setProperty(ElementPropertiesDefaultNames.TEXT_BODY,
Main.getTextBody(tp)) ;
replacement.put(index, title) ;
// System.out.printf("Ajout d'un titre à l'indice %d, contenu '%s'\n",
// index, title.getProperty(ElementPropertiesDefaultNames.TEXT_BODY)) ;
}// if
}// if
}// if
index++ ;
}// for
for(Integer pos : replacement.keySet()) {
d.remove(pos) ;
if (pos == d.getCount()) {
d.append(replacement.get(pos)) ;
} else {
d.add(replacement.get(pos), pos) ;
}// if
}// for
}// refactorTitles(Document)
protected static void refactorParagraphs(Document d) {
refactorParagraphs(d.getParagraphs()) ;
}// removeEmptyParagraphs(Document)
protected static void refactorParagraphs(Paragraphs paragraphs) {
for(Iterator<Paragraph> iter=paragraphs.iterator(); iter.hasNext(); ) {
Paragraph p = iter.next() ;
if (p instanceof TextParagraph) {
TextParagraph tp = (TextParagraph) p ;
if (tp.getCount() == 0) {
iter.remove() ;
} else {
fuseTextParts(tp) ;
}// if
} else if (p instanceof Array) {
Array array = (Array) p ;
for(Row row : array) {
for(Cell cell : row) {
refactorParagraphs(cell.getParagraphs()) ;
}// for
}// for
}// if
}// for
}// removeEmptyParagraphs(Document)
protected static void fuseTextParts(TextParagraph tp) {
Iterator<TextParagraphElement> iter = tp.iterator() ;
TextParagraphElement nextElement ;
List<Integer> removed = new ArrayList<Integer>() ;
int currentIndex = -1 ;// Position of nextElement
while (iter.hasNext()) {
nextElement = iter.next() ;
currentIndex++ ;
if (nextElement instanceof Text) {
while (fuseText((Text) nextElement, currentIndex, iter, removed)) {
currentIndex++ ;
}// while
currentIndex++ ;
}// if
}// while
for (Integer removedIndex : removed) {
System.out.printf("Removing index: %d\n", removedIndex);
try {
tp.remove(removedIndex.intValue()) ;
} catch (InvalidIndexException e) {
// TODO Auto-generated catch block
// This hsould not happen !
}// try
}// for
}// fuseTextParts(TextParagraph)
private static boolean fuseText(Text current, int currentIndex,
Iterator<TextParagraphElement> following, List<Integer> removed) {
boolean fused = false ;
if (following.hasNext()) {
TextParagraphElement next = following.next() ;
currentIndex++ ;
if (next instanceof Text) {
Text nextText = (Text) next ;
if (equals(current, nextText)) {
try {
current.setProperty(ElementPropertiesDefaultNames.TEXT_BODY,
String.format("%s%s",
current.getProperty(ElementPropertiesDefaultNames.TEXT_BODY),
nextText.getProperty(ElementPropertiesDefaultNames.TEXT_BODY))) ;
if (removed.isEmpty()) {
removed.add(new Integer(currentIndex)) ;
} else {
removed.add(0, new Integer(currentIndex)) ;
}
fused = true ;
} catch (InvalidPropertyException e) {
// TODO: handle exception
// This hsould not happen !
}// try
}// if
}// if
}// if
return fused ;
}// fuseText(Text current, Iterator<TextParagraphElement>)
private static boolean equals(Text a, Text b) {
boolean equal = true ;
String[] params = new String[]{
ElementPropertiesDefaultNames.FORMAT_BOLD,
ElementPropertiesDefaultNames.FORMAT_ITALIC,
ElementPropertiesDefaultNames.FORMAT_MONOSPACE,
ElementPropertiesDefaultNames.FORMAT_STRUCK,
ElementPropertiesDefaultNames.FORMAT_SUBSCRIPT,
ElementPropertiesDefaultNames.FORMAT_SUPERSCRIPT,
ElementPropertiesDefaultNames.FORMAT_UNDERLINED
} ;
try {
System.out.printf("Comparing ...\n'%s'\n%s\n\twith\n'%s'\n%s\n",
a.getProperty(ElementPropertiesDefaultNames.TEXT_BODY), a,
b.getProperty(ElementPropertiesDefaultNames.TEXT_BODY), b) ;
} catch (InvalidPropertyException e) {
/* Will not happen ! */
}// try
int p = 0, maxP = params.length ;
while (equal && (p < maxP)) {
String key = params[p] ;
try {
equal = (a.isProperty(key) && a.getProperty(key).equals(b.getProperty(key)))
|| (!a.isProperty(key) && !b.isProperty(key)) ;
} catch (InvalidPropertyException e) {
/* Will not happen ! */
}// try
++p ;
}// while
System.out.printf("Result: %b\n", equal) ;
return equal ;
}// equals(Text, Text)
protected static int getTitleLevel(String style) {
final String[] titleStyles = new String[]{
"Titre1", "Titre2", "Titre3", "Titre4", "Titre5"
} ;
int index = Arrays.binarySearch(titleStyles, style) ;
if (index >= 0) {
index++ ;
}// if
return index ;
}// getTitleLevel(String)
protected static String getTextBody(TextParagraph p) {
StringBuilder text = new StringBuilder() ;
for(TextParagraphElement el : p) {
try {
text.append(el.getProperty(ElementPropertiesDefaultNames.TEXT_BODY)) ;
} catch (InvalidPropertyException e) {
/* This should not happen. */
}// try
}// for
return text.toString() ;
}// getTextBody(TextParagraph)
protected static void refactorTables(Document d) {
for(Paragraph p : d) {
if (p instanceof Array) {
Array array = (Array) p ;
if (array.getCount() <= 0) {
continue ;
}// if
Row firstRow = array.iterator().next() ;
boolean isHeaderRow = true ;
for(Iterator<Cell> iter = firstRow.iterator(); iter.hasNext() && isHeaderRow; ) {
Cell cell = iter.next() ;
for(Iterator<Paragraph> cellIter = cell.iterator(); cellIter.hasNext() && isHeaderRow; ) {
Paragraph paragraph = cellIter.next() ;
if (paragraph instanceof TextParagraph) {
TextParagraph tp = (TextParagraph) paragraph ;
for(Iterator<TextParagraphElement> tpIter = tp.iterator(); tpIter.hasNext() && isHeaderRow; ) {
TextParagraphElement element = tpIter.next() ;
try {
isHeaderRow = Boolean.TRUE.equals(element.getProperty(ElementPropertiesDefaultNames.FORMAT_BOLD)) ;
} catch (InvalidPropertyException e) {
/* This should not happen. */
}// try
}// for
} else {
try {
isHeaderRow = Boolean.TRUE.equals(p.getProperty(ElementPropertiesDefaultNames.FORMAT_BOLD)) ;
} catch (InvalidPropertyException e) {
/* This should not happen. */
}// try
}// if
}// for
}// for
if (isHeaderRow) {
int nCells = firstRow.getCount() ;
for(int cellIndex=0; cellIndex < nCells; ++cellIndex) {
CellHeader header = new CellHeader(firstRow.getCell(cellIndex)) ;
try {
firstRow.add(header, cellIndex) ;
firstRow.remove(cellIndex+1) ;
} catch (KameleonException e) {/* Never called. */}
}// for
}// if
}// if
}// for
}// refactorTables(Document)
protected static void printDocumentContent(Document d) {
System.out.printf("Document : %d elements", d.getCount()) ;
for(Paragraph p : d) {
System.out.printf("\t- %s\n", p.getClass()) ;
}// for
}// printDocumentContent(Document)
/**
*
*/
@Override
public Document analyze(String filePath, SupportedOptions options) throws KameleonException {
/* Analyze file */
Document d = Main.analyzeFile(filePath) ;
/* Correct analyze flaws */
Main.refactorTitles(d) ;
Main.refactorParagraphs(d) ;
Main.refactorTables(d) ;
return d ;
}// analyze(String filePath, SupportedOptions)
@Override
public Document analyze(String filePath) throws KameleonException {
return this.analyze(filePath, this.getDefaultOptions()) ;
}
@Override
public void copyPicture(String targetFolder) throws KameleonException {
String[] pictureNames = new String[]{
"WordML2003Analyzer_mini.png",
"WordML2003Analyzer_gray_icon.png",
"WordML2003Analyzer_icon.png"
} ;
for(String pictureName : pictureNames) {
try {
InputStream src = new BufferedInputStream(
this.getClass().getResourceAsStream(
String.format("/aword/ressources/%s", pictureName))) ; //$NON-NLS-1$
OutputStream dest = new BufferedOutputStream(new FileOutputStream(String.format("%s%s%s",
targetFolder, File.separator, pictureName))) ;
IOFile.copyFile(src, dest) ;
src.close() ;
dest.close() ;
} catch (FileNotFoundException e) {
//TODO Handle exception
throw new KameleonException(e.getMessage()) ;
} catch (IOException e) {
throw new KameleonException(e.getMessage()) ;
}// try
}// for
}
protected SupportedOptions getDefaultOptions() {
return null ;
}
}// class Main