package org.openxml4j.document.wordprocessing;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.QName;
/**
* Repr�sente un paragraphe. <b>Attention, ce code de d�monstration ne prend ne
* tient pas compte des styles et autres informations du document. Ainsi les
* propri�t�s des paragraphes et des runs en plus d'�tre incompl�tes, ne sont
* pas correctement impl�ment�es, donc non valides avec les sp�cifications.
* Cependant, cette impl�mentation suffit � cette d�monstration.</b>
*
* @author Julien Chable
*/
public final class Paragraph {
/**
* L'alignement du paragraphe.
*/
protected ParagraphAlignment alignment;
/**
*/
protected boolean bold;
/**
*/
protected boolean italic;
protected UnderlineStyle underline;
protected int paragraphRefInNumberingXml = ParagraphBuilder.PARAGRAPH_NUMBERING_NONE; // reference
// in
// numbering.xml
// (generate
// tag
// w:numId)
protected int paragraphNumberShift = 0; // 0 for para like 1, 1 for para
// like 1.2, 2 for 1.2.3, 3 for
// 1.2.3.4 ....
/**
* the style name should be related to the style described in style.xml The
* style will be used to generate TOC
*/
protected String paragraphStyleName = ParagraphBuilder.DEFAULT_PARAGRAPH_STYLE;
/**
* space above and below paragraph
*/
private ParagraphSpacing spacing;
/**
* in a read only document, allow some paragraph to be editable
*/
private ParagraphReadOnlyManager readOnlyPermission = null;
/**
*/
protected int fontSize;
/**
* La liste des Runs dans l'ordre dans lesquels ceux-ci ont �t� ajout�s.
*/
//#ifdef JAVA5
protected ArrayList<Run> runs;
//#else
/*
protected ArrayList runs;
*/
//#endif
/**
* Pr�vient la construction de paragraphe.
*/
protected Paragraph() {
//#ifdef JAVA5
runs = new ArrayList<Run>();
//#else
/*
runs = new ArrayList();
*/
//#endif
spacing = new ParagraphSpacing();
}
/**
* Ajoute un Run � ce paragraphe.
*
* @param run
* Le Run � ajouter.
*/
public void addRun(Run run) {
runs.add(run);
}
/**
* @param text
* @return the run created
*/
public void addTextAsRunWithParagraphSetting(String text) {
Run run = new Run(text);
// configure the run as the defaults for this paragraph are
run.setBold(bold);
run.setItalic(italic);
run.setUnderline(underline);
run.setFontSize(fontSize);
// add it to the list
runs.add(run);
}
private void addParagraphProperties( Element paragraph) {
Element properties=paragraph.addElement(new QName(WordprocessingML.PARAGRAPH_PROPERTIES_TAG_NAME, WordDocument.namespaceWord));
// w:pPr
// Alignement
Element paraAlignement=properties.addElement(new QName(WordprocessingML.PARAGRAPH_ALIGNEMENT_TAG_NAME, WordDocument.namespaceWord));
paraAlignement.addAttribute(new QName(WordprocessingML.PROPERTIES_VALUE_TAG_NAME, WordDocument.namespaceWord), alignment.toString());
if (paragraphRefInNumberingXml != ParagraphBuilder.PARAGRAPH_NUMBERING_NONE) {
// add numbering
/*
* add somthing like
* <w:numPr>
* <w:ilvl w:val="1"/>
* <w:numId w:val="1"/>
* </w:numPr>
*/
Element paraNumbering=properties.addElement(new QName(WordprocessingML.PARAGRAPH_NUMBERING_TAG_NAME, WordDocument.namespaceWord));
// now <w:numId w:val="1"/>
Element numberingLevelReference=paraNumbering.addElement(new QName(WordprocessingML.PARAGRAPH_NUMBERING_LEVEL_REFERENCE, WordDocument.namespaceWord));
numberingLevelReference.addAttribute(
new QName(WordprocessingML.PROPERTIES_VALUE_TAG_NAME, WordDocument.namespaceWord),
(new Integer(paragraphNumberShift).toString()));
// make <w:ilvl w:val="1"/>
Element numberingReferenceInNumberingXml=paraNumbering.addElement(new QName(WordprocessingML.PARAGRAPH_NUMBERING_REFERENCE, WordDocument.namespaceWord));
numberingReferenceInNumberingXml.addAttribute(
new QName(WordprocessingML.PROPERTIES_VALUE_TAG_NAME, WordDocument.namespaceWord),
(new Integer(paragraphRefInNumberingXml).toString()));
}
// add the paragraph style
// like <w:pStyle w:val="Normal"/>
addParameterStyleXmlCode(properties);
if (spacing.isSpacingRequired()) {
spacing.addParagraphSpacingProperties( properties);
// add spacing is needed
// something like <w:spacing w:before="240" w:after="120"/>
}
}
private Element addParameterStyleXmlCode(Element paraProperties) {
return Paragraph.addParameterStyleXmlCode(paraProperties,
paragraphStyleName);
}
private static Element addParameterStyleXmlCode(Element paraProperties,
String styleName) {
Element paraStyle= paraProperties.addElement(new QName(WordprocessingML.PARAGRAPH_STYLE, WordDocument.namespaceWord));
paraStyle.addAttribute(new QName(WordprocessingML.PROPERTIES_VALUE_TAG_NAME, WordDocument.namespaceWord), styleName);
return paraStyle;
}
public static void addDefaultStyleXmlCode(Element paraNode) {
// check paragraph has property node
Element propertiesNode = hasProperties(paraNode);
if (propertiesNode != null) {
// add to properties
addParameterStyleXmlCode(propertiesNode,
ParagraphBuilder.DEFAULT_PARAGRAPH_STYLE);
} else {
// add properties node (w:pPr) and then the style as child
propertiesNode=paraNode.addElement(new QName(WordprocessingML.PARAGRAPH_PROPERTIES_TAG_NAME, WordDocument.namespaceWord));
addParameterStyleXmlCode(propertiesNode,
ParagraphBuilder.DEFAULT_PARAGRAPH_STYLE);
}
}
public static Element hasProperties(Element nodeToCheck) {
return hasTag(nodeToCheck,
WordprocessingML.PARAGRAPH_PROPERTIES_TAG_NAME);
}
public static Element hasStyleName(Element nodeToCheck) {
Element propertiesNode = Paragraph.hasProperties(nodeToCheck);
if (propertiesNode == null) {
// no properties for paragraph, therefore no style
return null;
}
return Paragraph.hasTag(propertiesNode,
WordprocessingML.PARAGRAPH_STYLE);
}
private static Element hasTag(Element nodeToCheck, String valueToSearchFor) {
List listOfElements=nodeToCheck.elements();
for (Iterator iter = listOfElements.iterator(); iter.hasNext();) {
Element element = (Element) iter.next();
if (element.getName().equals(valueToSearchFor)){
//tag found
return element;
}
}
return null; // all children of paragraph have been checked and none
// has the required tag
}
/**
* build a paragraph in open XML
*
* @return
*/
public Element build() {
DocumentFactory factory=DocumentFactory.getInstance();
Element paragraph=factory.createElement(new QName(WordprocessingML.PARAGRAPH_BODY_TAG_NAME, WordDocument.namespaceWord));
// Element paragraph=insertionPoint.addElement(new QName(WordprocessingML.PARAGRAPH_BODY_TAG_NAME, WordDocument.namespaceWord));
// add paragraph properties
addParagraphProperties( paragraph);
// in a read only document, is this paragraph write enabled ?
if (readOnlyPermission != null) {
readOnlyPermission.addReadOnlyStartTag( paragraph);
}
// add Runs
addRunsInParagraph( paragraph);
// in a read only document, is this paragraph write enabled ?
if (readOnlyPermission != null) {
readOnlyPermission.addReadOnlyEndTag( paragraph);
}
return paragraph;
}
private void addRunsInParagraph(Element paragraph) {
//#ifdef JAVA5
for (Run r : runs) {
//#else
/*
Iterator iter = runs.iterator(); while (iter.hasNext()) {
Run r = (Run) iter.next();
*/
//#endif
Element run=paragraph.addElement(new QName(WordprocessingML.PARAGRAPH_RUN_TAG_NAME, WordDocument.namespaceWord));
// properties
Element runProps=run.addElement(new QName(WordprocessingML.RUN_PROPERTIES_TAG_NAME, WordDocument.namespaceWord));
// Bold
if (r.isBold()) {
runProps.addElement(
new QName(WordprocessingML.RUN_BOLD_PROPERTY_TAG_NAME,
WordDocument.namespaceWord));
}
// Italic
if (r.isItalic()) {
runProps.addElement(
new QName(WordprocessingML.RUN_ITALIC_PROPERTY_TAG_NAME,
WordDocument.namespaceWord));
}
if (r.getUnderline() != UnderlineStyle.NONE) {
Element underlineProp=runProps.addElement(
new QName(WordprocessingML.RUN_UNDERLINE_PROPERTY_TAG_NAME,
WordDocument.namespaceWord));
underlineProp.addAttribute(
new QName(WordprocessingML.PROPERTIES_VALUE_TAG_NAME,WordDocument.namespaceWord),
r.getUnderline().toString());
}
// vertical alignment
if (r.getVerticalAlignement() != VerticalAlignment.NONE) {
Element vertAlignProp=runProps.addElement(
new QName(WordprocessingML.RUN_VERTICAL_ALIGNEMENT_PROPERTY_TAG_NAME,WordDocument.namespaceWord));
vertAlignProp.addAttribute(
new QName(WordprocessingML.PROPERTIES_VALUE_TAG_NAME,WordDocument.namespaceWord),
r.verticalAlignement.toString());
}
// font size
Element fontSizeProp=runProps.addElement(
new QName(WordprocessingML.RUN_FONT_SIZE_PROPERTY_TAG_NAME,WordDocument.namespaceWord));
fontSizeProp.addAttribute(
new QName(WordprocessingML.PROPERTIES_VALUE_TAG_NAME,WordDocument.namespaceWord),
"" + r.fontSize);
// text
Element text=run.addElement(
new QName(WordprocessingML.RUN_TEXT,WordDocument.namespaceWord));
if (r.getText().indexOf(" ") != -1) {
//take care of space in text
text.addAttribute(
"xml:space",
"preserve");
}
text.addText(r.getText());
}
}
/* Accesseurs */
/**
* @return the alignment
* @uml.property name="alignment"
*/
public ParagraphAlignment getAlignment() {
return alignment;
}
/**
* @param alignment
* the alignment to set
* @uml.property name="alignment"
*/
public void setAlignment(ParagraphAlignment alignment) {
this.alignment = alignment;
}
/**
* @return the bold
* @uml.property name="bold"
*/
public boolean isBold() {
return bold;
}
/**
* @param bold
* the bold to set
* @uml.property name="bold"
*/
public void setBold(boolean bold) {
this.bold = bold;
}
/**
* @return the fontSize
* @uml.property name="fontSize"
*/
public int getFontSize() {
return fontSize;
}
/**
* @param fontSize
* the fontSize to set
* @uml.property name="fontSize"
*/
public void setFontSize(int fontSize) {
this.fontSize = fontSize;
}
/**
* @return the italic
* @uml.property name="italic"
*/
public boolean isItalic() {
return italic;
}
/**
* @param italic
* the italic to set
* @uml.property name="italic"
*/
public void setItalic(boolean italic) {
this.italic = italic;
}
/**
* @return the underline
* @uml.property name="underline"
*/
public UnderlineStyle getUnderline() {
return underline;
}
/**
* @param underline
* the underline to set
* @uml.property name="underline"
*/
public void setUnderline(UnderlineStyle underline) {
this.underline = underline;
}
public int getParagraphNumberShift() {
return paragraphNumberShift;
}
public void setParagraphNumberShift(int paragraphNumberShift) {
this.paragraphNumberShift = paragraphNumberShift;
}
public int getParagraphRefInNumberingXml() {
return paragraphRefInNumberingXml;
}
public void setParagraphRefInNumberingXml(int paragraphRefInNumberingXml) {
this.paragraphRefInNumberingXml = paragraphRefInNumberingXml;
}
public ParagraphSpacing getSpacing() {
return spacing;
}
public void setSpacing(ParagraphSpacing spacing) {
this.spacing = spacing;
}
public void setSpacing(ParagraphSpacingPredefined spacing) {
this.spacing = new ParagraphSpacing(spacing);
}
public ParagraphReadOnlyManager getReadOnlyPermission() {
return readOnlyPermission;
}
public void setReadOnlyPermission(
ParagraphReadOnlyManager readOnlyPermission) {
this.readOnlyPermission = readOnlyPermission;
}
public String getParagraphStyleName() {
return paragraphStyleName;
}
public void setParagraphStyleName(String paragraphStyleName) {
this.paragraphStyleName = paragraphStyleName;
}
}