diff --git a/document/fr.opensagres.xdocreport.document.docx/src/main/java/fr/opensagres/xdocreport/document/docx/textstyling/DocxDocumentHandler.java b/document/fr.opensagres.xdocreport.document.docx/src/main/java/fr/opensagres/xdocreport/document/docx/textstyling/DocxDocumentHandler.java index 2b4a11dec..88e054328 100644 --- a/document/fr.opensagres.xdocreport.document.docx/src/main/java/fr/opensagres/xdocreport/document/docx/textstyling/DocxDocumentHandler.java +++ b/document/fr.opensagres.xdocreport.document.docx/src/main/java/fr/opensagres/xdocreport/document/docx/textstyling/DocxDocumentHandler.java @@ -68,6 +68,8 @@ public class DocxDocumentHandler private Stack paragraphsStack; + private Stack tableStack; + private Stack spansStack; private HyperlinkRegistry hyperlinkRegistry; @@ -109,6 +111,7 @@ public void startDocument() this.paragraphsStack = new Stack(); this.spansStack = new Stack(); this.addLineBreak = 0; + this.tableStack = new Stack(); } public void endDocument() @@ -320,10 +323,8 @@ private void processRunProperties( boolean isInsidePPr, boolean bold, boolean it private void startParagraphIfNeeded() throws IOException { - - if ( paragraphWasInserted && paragraphsStack.isEmpty() ) - { - internalStartParagraph( null ); + if (((paragraphWasInserted || !tableStack.isEmpty()) && paragraphsStack.isEmpty())) { + internalStartParagraph(null); } } @@ -735,6 +736,8 @@ protected void doStartTable( TableProperties properties ) // w:tblGrid // that's here temp writer is used. pushTempWriter(); + //Control if inside table + tableStack.push(true); } public void doEndTable( TableProperties properties ) @@ -751,7 +754,8 @@ public void doEndTable( TableProperties properties ) popTempWriter( startTable.toString() ); super.write( "" ); // if table is inside a table cell, a paragraph is required. - super.write( "" ); + super.write(""); + tableStack.pop(); } public void doStartTableRow( TableRowProperties properties ) @@ -773,14 +777,16 @@ public void doStartTableCell( TableCellProperties properties ) /* * super.write( "" ); super.write( "" ); super.write( "" ); */ - internalStartParagraph( null ); + if (properties != null) { + internalStartParagraph(properties); + } } public void doEndTableCell() - throws IOException + throws IOException { - endParagraph(); + endParagraphIfNeeded(); super.write( "" ); } diff --git a/document/fr.opensagres.xdocreport.document.docx/src/test/java/fr/opensagres/xdocreport/document/docx/textstyling/DocxDocumentHandlerTestCase.java b/document/fr.opensagres.xdocreport.document.docx/src/test/java/fr/opensagres/xdocreport/document/docx/textstyling/DocxDocumentHandlerTestCase.java index 4f5e32b3d..ec0486f77 100644 --- a/document/fr.opensagres.xdocreport.document.docx/src/test/java/fr/opensagres/xdocreport/document/docx/textstyling/DocxDocumentHandlerTestCase.java +++ b/document/fr.opensagres.xdocreport.document.docx/src/test/java/fr/opensagres/xdocreport/document/docx/textstyling/DocxDocumentHandlerTestCase.java @@ -731,6 +731,32 @@ public void testTable() handler.getTextEnd() ); } + @Test + public void testStyledTable() + throws Exception { + IContext context = new MockContext(); + BufferedElement parent = null; + + ITextStylingTransformer formatter = HTMLTextStylingTransformer.INSTANCE; + IDocumentHandler handler = new DocxDocumentHandler(parent, context, "word/document.xml"); + formatter.transform("" + + "" + + "" + + "" + + "
AB
CD
EF
", + handler); + + Assert.assertEquals("", handler.getTextBefore()); + Assert.assertEquals("", handler.getTextBody()); + Assert.assertEquals("" + + "" + + "AB" + + "CD" + + "EF" + + "", + handler.getTextEnd()); + } + @Test public void testAll() throws Exception diff --git a/document/fr.opensagres.xdocreport.document.odt/src/main/java/fr/opensagres/xdocreport/document/odt/textstyling/ODTDocumentHandler.java b/document/fr.opensagres.xdocreport.document.odt/src/main/java/fr/opensagres/xdocreport/document/odt/textstyling/ODTDocumentHandler.java index 59a6907d4..1f8ffac93 100644 --- a/document/fr.opensagres.xdocreport.document.odt/src/main/java/fr/opensagres/xdocreport/document/odt/textstyling/ODTDocumentHandler.java +++ b/document/fr.opensagres.xdocreport.document.odt/src/main/java/fr/opensagres/xdocreport/document/odt/textstyling/ODTDocumentHandler.java @@ -51,8 +51,21 @@ public class ODTDocumentHandler private boolean insideHeader = false; + private Stack tableStack; + private Stack spanStack; + /** + * Stores each nested tag added to the document. + * Required to verify if a new paragraph can be added. + * Paragraphs cannot be direct children of another paragraph, but they + * can, sometimes, be nested if there are other tags between them, like + * a list and a list-item. + * + * Relevant document: http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#__RefHeading__1415138_253892949 + */ + private Stack nestedTagStack; + private int listDepth = 0; private List lastItemAlreadyClosed = new ArrayList(); @@ -75,6 +88,8 @@ public void startDocument() { this.paragraphsStack = new Stack(); this.spanStack = new Stack(); + this.tableStack = new Stack(); + this.nestedTagStack = new Stack(); } public void endDocument() @@ -237,6 +252,8 @@ private void internalStartSpan( String styleName, boolean push ) { spanStack.push( 1 ); } + + pushNestedTag("span"); } private void internalEndSpan() @@ -249,6 +266,7 @@ private void internalEndSpan() while ( depth > 0 ) { super.write( "" ); + popNestedTag("span"); depth--; } } @@ -256,9 +274,7 @@ private void internalEndSpan() private void startParagraphIfNeeded() throws IOException { - - if ( ( paragraphWasInserted && paragraphsStack.isEmpty() ) || closeHeader ) - { + if (((paragraphWasInserted || !tableStack.isEmpty()) && paragraphsStack.isEmpty()) || closeHeader) { internalStartParagraph( false, (String) null ); } } @@ -266,10 +282,14 @@ private void startParagraphIfNeeded() public void startParagraph( ParagraphProperties properties ) throws IOException { - if ( paragraphsStack.isEmpty() || !paragraphsStack.peek() ) + if ( !paragraphsStack.isEmpty() && !paragraphsStack.peek() ) { - super.setTextLocation( TextLocation.End ); - internalStartParagraph( false, properties ); + internalEndParagraph(); + } + + if(nestedTagStack.isEmpty() || !"p".equals(nestedTagStack.peek())) { + super.setTextLocation(TextLocation.End); + internalStartParagraph(false, properties); } } @@ -304,15 +324,6 @@ else if ( properties.isPageBreakBefore() ) } } internalStartParagraph( containerIsList, styleName ); - - // if ( properties != null ) - // { - // // Remove "span" added by internalStartParagraph - // // spanStack.pop(); - // - // // Process properties - // // startSpan( properties ); - // } } private void internalStartParagraph( boolean containerIsList, String styleName ) @@ -335,6 +346,7 @@ private void internalStartParagraph( boolean containerIsList, String styleName ) // Put a 0 in the stack, endSpan is called when a paragraph is ended spanStack.push( 0 ); + pushNestedTag("p"); } private void internalEndParagraph() @@ -345,8 +357,10 @@ private void internalEndParagraph() // Close any spans from paragraph style internalEndSpan(); + super.write( "" ); paragraphsStack.pop(); + popNestedTag("p"); } } @@ -359,6 +373,7 @@ public void startHeading( int level, HeaderProperties properties ) + level + "\">" ); insideHeader = true; closeHeader = false; + pushNestedTag("h"); } public void endHeading( int level ) @@ -367,6 +382,7 @@ public void endHeading( int level ) super.write( "" ); insideHeader = false; closeHeader = true; + popNestedTag("h"); // startParagraph(); } @@ -427,6 +443,7 @@ protected void internalStartList( String style ) super.write( "" ); } listDepth++; + pushNestedTag("list"); } protected void internalEndList() @@ -438,11 +455,14 @@ protected void internalEndList() { // startParagraph(); } + + popNestedTag("list"); } public void startListItem( ListItemProperties properties ) throws IOException { + pushNestedTag("list-item"); if ( itemStyle != null ) { super.write( "" ); @@ -453,6 +473,8 @@ public void startListItem( ListItemProperties properties ) super.write( "" ); internalStartParagraph( true, (String) null ); } + + } public void endListItem() @@ -468,6 +490,7 @@ public void endListItem() } endParagraphIfNeeded(); super.write( "" ); + popNestedTag("list-item"); } public void startSpan( SpanProperties properties ) @@ -515,6 +538,8 @@ protected void doStartTable( TableProperties properties ) // table:table-column // that's here temp writer is used. pushTempWriter(); + //Control if inside table + tableStack.push(true); } public void doEndTable( TableProperties properties ) @@ -529,32 +554,52 @@ public void doEndTable( TableProperties properties ) startTable.append( "\" >" ); startTable.append( "" ); popTempWriter( startTable.toString() ); - super.write( "" ); + super.write(""); + tableStack.pop(); } protected void doStartTableRow( TableRowProperties properties ) throws IOException { super.write( "" ); + pushNestedTag("table-row"); } protected void doEndTableRow() throws IOException { super.write( "" ); + popNestedTag("table-row"); } protected void doStartTableCell( TableCellProperties properties ) throws IOException { - super.write( "" ); - internalStartParagraph( false, (String) null ); + super.write(""); + pushNestedTag("table-cell"); + if (properties != null) { + internalStartParagraph(false, styleGen.getTextStyleName(properties)); + } } public void doEndTableCell() - throws IOException + throws IOException { - endParagraph(); - super.write( "" ); + endParagraphIfNeeded(); + super.write(""); + popNestedTag("table-cell"); + } + + private void popNestedTag(String tag) { + String stackTag = nestedTagStack.peek(); + if(stackTag.equals(tag)) { + nestedTagStack.pop(); + } else { + throw new RuntimeException("Invalid nested tag. Should be <" + tag + "> found <" + stackTag + ">."); + } + } + + private void pushNestedTag(String tag) { + nestedTagStack.push(tag); } } diff --git a/document/fr.opensagres.xdocreport.document.odt/src/test/java/fr/opensagres/xdocreport/document/odt/textstyling/ODTDocumentHandlerTestCase.java b/document/fr.opensagres.xdocreport.document.odt/src/test/java/fr/opensagres/xdocreport/document/odt/textstyling/ODTDocumentHandlerTestCase.java index 83873268d..cac016dfb 100644 --- a/document/fr.opensagres.xdocreport.document.odt/src/test/java/fr/opensagres/xdocreport/document/odt/textstyling/ODTDocumentHandlerTestCase.java +++ b/document/fr.opensagres.xdocreport.document.odt/src/test/java/fr/opensagres/xdocreport/document/odt/textstyling/ODTDocumentHandlerTestCase.java @@ -775,7 +775,7 @@ public void testHeaderAndTextAndParagraph() Assert.assertEquals( "", handler.getTextBefore() ); Assert.assertEquals( "", handler.getTextBody() ); - Assert.assertEquals( "Title1textparagraph", + Assert.assertEquals( "Title1textparagraph", handler.getTextEnd() ); } @@ -1057,7 +1057,7 @@ public void testSpansInP() @Test public void testTable() - throws Exception + throws Exception { IContext context = new MockContext(); BufferedElement parent = null; @@ -1075,10 +1075,36 @@ public void testTable() Assert.assertEquals( "", handler.getTextBody() ); Assert.assertEquals( "" + "" - + "AB" - + "CD" - + "EF" - + "", + + "AB" + + "CD" + + "EF" + + "", handler.getTextEnd() ); } + + @Test + public void testStyledTable() + throws Exception { + IContext context = new MockContext(); + BufferedElement parent = null; + + ITextStylingTransformer formatter = HTMLTextStylingTransformer.INSTANCE; + IDocumentHandler handler = new ODTDocumentHandler(parent, context, "content.xml"); + formatter.transform("" + + "" + + "" + + "" + + "
AB
CD
EF
", + handler); + + Assert.assertEquals("", handler.getTextBefore()); + Assert.assertEquals("", handler.getTextBody()); + Assert.assertEquals("" + + "" + + "AB" + + "CD" + + "EF" + + "", + handler.getTextEnd()); + } } diff --git a/document/fr.opensagres.xdocreport.document.odt/src/test/resources/OOoResult.xml b/document/fr.opensagres.xdocreport.document.odt/src/test/resources/OOoResult.xml index a5919dc23..3b784acfa 100644 --- a/document/fr.opensagres.xdocreport.document.odt/src/test/resources/OOoResult.xml +++ b/document/fr.opensagres.xdocreport.document.odt/src/test/resources/OOoResult.xml @@ -72,12 +72,12 @@ bold text italic text XDocReport - - Template style - - - Template style inheritance - + + + Template style + + + Template style inheritance diff --git a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/dispatcher/BasicXDocReportDispatcher.java b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/dispatcher/BasicXDocReportDispatcher.java index a38996d8b..a57bd6946 100644 --- a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/dispatcher/BasicXDocReportDispatcher.java +++ b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/dispatcher/BasicXDocReportDispatcher.java @@ -28,6 +28,7 @@ import java.util.LinkedHashMap; import java.util.Map; + public class BasicXDocReportDispatcher extends AbstractXDocReportDispatcher { @@ -46,22 +47,17 @@ public T getReportController( String reportId ) public void register( String reportId, T controller ) { - - controllersMap.put( reportId, controller ); + controllersMap.put(reportId, controller); } - public void unregister( T controller ) + public void unregister( final T controller ) { - controllersMap.remove( controller ); + controllersMap.values().remove(controller); } public void unregister( String reportId ) { - T controller = controllersMap.get( reportId ); - if ( controller != null ) - { - unregister( controller ); - } + controllersMap.remove( reportId ); } public Collection getControllers() diff --git a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/AbstractDocumentHandler.java b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/AbstractDocumentHandler.java index 8765c54fa..751fe52f8 100644 --- a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/AbstractDocumentHandler.java +++ b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/AbstractDocumentHandler.java @@ -163,8 +163,8 @@ public final void startTableCell( TableCellProperties properties ) throws IOException { TableProperties tableProperties = this.tablesStack.peek(); - tableProperties.setColumnCount( tableProperties.getColumnCount() + 1 ); - doStartTableCell( properties ); + tableProperties.setColumnCount(tableProperties.getColumnCount() + 1); + doStartTableCell(properties); } public final void endTableCell() @@ -334,5 +334,5 @@ protected abstract void doStartTableCell( TableCellProperties properties ) throws IOException; protected abstract void doEndTableCell() - throws IOException; + throws IOException; } diff --git a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/html/HTMLTextStylingContentHandler.java b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/html/HTMLTextStylingContentHandler.java index 4714eaddc..a2a98b3b0 100644 --- a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/html/HTMLTextStylingContentHandler.java +++ b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/html/HTMLTextStylingContentHandler.java @@ -295,7 +295,7 @@ else if ( TR_ELT.equals( name ) ) else if ( TD_ELT.equals( name ) ) { // - TableCellProperties properties = StylesHelper.createTableCellProperties( attributes ); + TableCellProperties properties = StylesHelper.createTableCellProperties(attributes.getValue(STYLE_ATTR)); documentHandler.startTableCell( properties ); } } diff --git a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/html/StylesHelper.java b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/html/StylesHelper.java index 7f28399ba..c4d22995a 100644 --- a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/html/StylesHelper.java +++ b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/html/StylesHelper.java @@ -282,9 +282,14 @@ public static TableRowProperties createTableRowProperties( Attributes attributes return properties; } - public static TableCellProperties createTableCellProperties( Attributes attributes ) - { - TableCellProperties properties = new TableCellProperties(); - return properties; + public static TableCellProperties createTableCellProperties(String style) { + Map stylesMap = StylesHelper.parse(style); + + if (!stylesMap.isEmpty()) { + TableCellProperties properties = new TableCellProperties(); + processContainerproperties(properties, stylesMap); + return properties; + } + return null; } } diff --git a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/properties/TableCellProperties.java b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/properties/TableCellProperties.java index dd6c9123c..061d5b80d 100644 --- a/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/properties/TableCellProperties.java +++ b/document/fr.opensagres.xdocreport.document/src/main/java/fr/opensagres/xdocreport/document/textstyling/properties/TableCellProperties.java @@ -28,6 +28,10 @@ * Table cell properties. */ public class TableCellProperties -{ + extends ContainerProperties { + + public TableCellProperties() { + super(ContainerType.PARAGRAPH); + } }