/*
* Copyright (c) 2012, Fromentin Xavier, Schnell Michaël, Dervin Cyrielle, Brabant Quentin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The names of its contributors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Fromentin Xavier, Schnell Michaël, Dervin Cyrielle OR Brabant Quentin
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package gword.generateur;
import gword.exception.WordGenerationException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Date;
import kameleon.document.Document;
import kameleon.exception.FileWritingException;
import kameleon.exception.KameleonException;
import kameleon.plugin.SupportedOptions;
/**
* //TODO
* @author Schnell Michaël
* @version 1.0
*/
public class WordMLGenerator extends DocumentBodyGenerator {
/**
* Stream used to generate the files.
*/
protected PrintWriter writer ;
/**
*
*/
public WordMLGenerator(boolean debugMode) {
super(debugMode) ;
}// WordMLGenerator()
/**
* //TODO Add javadoc
*
* @param base
*
*
* @param targetFile
*
*
* @param options
*
*
* @throws KameleonException
*
*/
public void generateDocument(Document base, String targetFile,
SupportedOptions options) throws KameleonException {
openDocument(targetFile) ;
fillDocument(base, options) ;
closeDocument() ;
}// generateDocument(Document, String, SupportedOptions)
/**
* Opens the stream used to write the file.
*
* @param targetPath
* absolute path of the generated file
*
* @throws FileWritingException
* if an error occurred while opening the target file
*/
protected void openDocument(String targetPath) throws FileWritingException {
this.targetFile = new File(targetPath) ;
try {
this.writer = new PrintWriter(new OutputStreamWriter(
new FileOutputStream(this.targetFile), WORD_CHARSET)) ;
} catch (IOException e) {
throw new FileWritingException(this.targetFile) ;
}// try
}// openDocument(String)
/**
* Generates the content of the opened file using the given instance
* of {@code Document}.
*
* @param base
* template for the generated content
*
* @param options
* options for the generation
*
* @throws KameleonException
* if an error occurred while generating the content
*/
protected void fillDocument(Document base, SupportedOptions options) throws KameleonException {
this.base = base ;
this.options = options ;
String content = String.format(WORD_DOCUMENT, this.generateDocument()) ;
this.writeDocument(content) ;
}// fillDocument(Document, SupportedOptions)
/**
* Closes the stream used to generate the file.
*/
protected void closeDocument() {
this.writer.close() ;
}// closeDocument()
/**
* Writes the given instance of {@code String} to the currently opened file.
*
* @param data
* written {@code String}
*/
protected void writeDocument(String data) {
this.writer.print(data) ;
}// writeDocument(String)
/**
* Returns the XML code of the WordML 2003 document.
*
* @return XML code of the WordML 2003 document
*
* @throws KameleonException
* if an error occurred while generating the XML code
*/
protected String generateDocument()
throws KameleonException {
StringBuilder builder = new StringBuilder() ;
builder.append(this.generateDocumentProperties()) ;
builder.append(this.generateFonts()) ;
builder.append(this.generateLists()) ;
builder.append(this.generateStyles()) ;
builder.append(this.generateDocPr()) ;
builder.append(this.generateBody()) ;
return builder.toString() ;
}// generateDocument(Document, SupportedOptions)
/**
* Generates the XML code for the document properties
* (tag: {@code <o:DocumentProperties>}).
*
* @return XML code for the document properties
* (tag: {@code <o:DocumentProperties>})
*
* @throws KameleonException
* if an error occurred while generating the XML code
*/
protected String generateDocumentProperties()
throws KameleonException {
//TODO Review the values
Date now = new Date() ;
String formattedNow = DATE_FORMATTER.format(now) ;
return String.format(DOCUMENT_PROPERTIES,
this.targetFile.getName(),
DOCUMENT_DEFAULT_AUTHOR,
DEFAULT_LAST_AUTHOR,
formattedNow,
formattedNow) ;
}// generateDocumentProperties(Document, SupportedOptions)
/**
* Generates the fonts definitions for a WordML document (tag: {@code <w:fonts>}).
*
* <p>Generates the definition of only one font, Times new Roman.
*
* @return XML code used to define the fonts of a WordML document
*
* @throws KameleonException
* if a error occurred while generating the XML code
*/
protected String generateFonts() throws KameleonException {
return FONTS ;
}// generateFonts()
/**
* Generates the XML code for the list styles (tag: {@code <w:lists>}).
*
* @return XML code for the list styles
*
* @throws KameleonException
* if an error occurred while generation the XML code
*/
protected String generateLists() throws KameleonException {
StringBuilder builder = new StringBuilder() ;
builder.append(this.generateListDefinitions()) ;
builder.append(this.generateListStyles()) ;
return String.format(LISTS, builder.toString()) ;
}// generateListDefinitions()
/**
* Generates the XML code of the list definitions (tag: {@code <w:listDef>}).
*
* <p>Generates the XML code for two list definitions:
* <ul>
* <li>a bullet list with four levels
* <li>a numbered list with four levels
* </ul>
*
* @return XML code of the list definitions
*
* @throws KameleonException
* if an error occurred while generating the XML code
*/
protected String generateListDefinitions() throws KameleonException {
StringBuilder bullet = new StringBuilder(),
numbered = new StringBuilder(),
defintion = new StringBuilder() ;
for(int level = 0, tabPos = MIN_TAB_POSITION; level < N_LEVELS;
++level, tabPos += TAB_STEP) {
Integer ilevel = new Integer(level),
itabPos = new Integer(tabPos) ;
// Generate the bullet level definitions
bullet.append(String.format(LIST_LEVEL_DEFINITION,
ilevel,
START_VALUE,
BULLET_LIST_TYPE,
BULLET_FORMAT,
JUSTIFICATION,
itabPos,
itabPos,
HANGING)) ;
// Generate the numbered level definitions
numbered.append(String.format(LIST_LEVEL_DEFINITION,
ilevel,
START_VALUE,
ilevel,
NUMBERING_FORMAT,
JUSTIFICATION,
itabPos,
itabPos,
HANGING)) ;
}// for
// Fuse the defintions
defintion.append(String.format(LIST_DEFINITION,
BULLET_LIST_ID, bullet.toString())) ;
defintion.append(String.format(LIST_DEFINITION,
NUMBERED_LIST_ID, numbered.toString())) ;
return defintion.toString() ;
}// generateListDefinitions()
/**
* Generates the XML code of the list styles (tag: {@code <w:list>}).
*
* @return XML code of the list styles
*
* @throws KameleonException
* if an error occurred while generating the XML code
*/
protected String generateListStyles() throws KameleonException {
StringBuilder defintion = new StringBuilder() ;
defintion.append(String.format(LIST_STYLE_DEFINITION,
BULLET_LIST_ID, BULLET_LIST_ID)) ;
defintion.append(String.format(LIST_STYLE_DEFINITION,
NUMBERED_LIST_ID, NUMBERED_LIST_ID)) ;
return defintion.toString() ;
}// generateListStyles()
/**
* Generates the XML code for the style definitions (tag: {@code <w:styles>}).
*
* @return XML code for the style definitions
*
* @throws KameleonException
* if an error occurred while generating the XML code
*/
protected String generateStyles() throws KameleonException {
StringBuilder styles = new StringBuilder() ;
// Generate the code for the basic paragraph style
styles.append(String.format(BASIC_STYLE_DEFINITION,
DEFAULT_STYLE_TYPE,
DEFAULT_IS_DEFAULT,
DEFAULT_NAME,
DEFAULT_NAME,
DEFAULT_GUI_NAME,
DEFAULT_FONT)) ;
// Generate the code for the heading
for(int heading=0; heading < N_HEADINGS; ++heading) {
Integer iheading = new Integer(heading+1),
outline = new Integer(heading);
String name = String.format(HEADING_NAME, iheading),
guiName = String.format(HEADING_GUI_NAME, iheading) ;
styles.append(String.format(HEADING_STYLE_DEFINITION,
name,
name,
guiName,
HEADING_NEXT_STYLE,
outline,
HEADING_FONT)) ;
}// for
// Generate the code for the arrays (tables)
styles.append(ARRAY_STYLE_DEFINITION) ;
return String.format(STYLES, styles.toString()) ;
}// generateStyles()
/**
* Generates the XML code for additional word document properties.
*
* @return XML code for additional word document properties
*
* @throws KameleonException
* if an error occurred while generating the XML code
*/
protected String generateDocPr() throws KameleonException {
return WORD_DOCUMENT_PROPERTIES ;
}// generateDocPr()
/**
* Generates the XML code for the {@code <w:body>} tag of the document.
*
* @return XML code for the {@code <w:body>} tag of the document
*
* @throws WordGenerationException
* if an error occurred while generating the XML code
*/
@Override
protected String generateBody() throws WordGenerationException {
return String.format(DOCUMENT_BODY, super.generateBody()) ;
}// generateBody()
}// class WordMLGenerator