Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.odftoolkit.odfdom.converter.internal.xhtml.ElementVisitorForXHTML Maven / Gradle / Ivy
/**
* Copyright (C) 2011-2012 The XDocReport Team
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.odftoolkit.odfdom.converter.internal.xhtml;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.odftoolkit.odfdom.converter.core.ElementVisitorConverter;
import org.odftoolkit.odfdom.converter.core.IURIResolver;
import org.odftoolkit.odfdom.converter.core.utils.ODFUtils;
import org.odftoolkit.odfdom.converter.core.utils.StringUtils;
import org.odftoolkit.odfdom.converter.xhtml.XHTMLOptions;
import org.odftoolkit.odfdom.doc.OdfDocument;
import org.odftoolkit.odfdom.dom.element.OdfStylableElement;
import org.odftoolkit.odfdom.dom.element.draw.DrawFrameElement;
import org.odftoolkit.odfdom.dom.element.draw.DrawImageElement;
import org.odftoolkit.odfdom.dom.element.office.OfficeMasterStylesElement;
import org.odftoolkit.odfdom.dom.element.office.OfficeTextElement;
import org.odftoolkit.odfdom.dom.element.style.StyleFooterElement;
import org.odftoolkit.odfdom.dom.element.style.StyleHeaderElement;
import org.odftoolkit.odfdom.dom.element.style.StyleMasterPageElement;
import org.odftoolkit.odfdom.dom.element.style.StyleTableColumnPropertiesElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableCellElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableColumnElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableRowElement;
import org.odftoolkit.odfdom.dom.element.text.TextAElement;
import org.odftoolkit.odfdom.dom.element.text.TextHElement;
import org.odftoolkit.odfdom.dom.element.text.TextLineBreakElement;
import org.odftoolkit.odfdom.dom.element.text.TextListElement;
import org.odftoolkit.odfdom.dom.element.text.TextListItemElement;
import org.odftoolkit.odfdom.dom.element.text.TextListLevelStyleElementBase;
import org.odftoolkit.odfdom.dom.element.text.TextListLevelStyleNumberElement;
import org.odftoolkit.odfdom.dom.element.text.TextPElement;
import org.odftoolkit.odfdom.dom.element.text.TextSpanElement;
import org.odftoolkit.odfdom.dom.style.OdfStyleFamily;
import org.odftoolkit.odfdom.incubator.doc.style.OdfStyle;
import org.odftoolkit.odfdom.incubator.doc.text.OdfTextListStyle;
import org.odftoolkit.odfdom.pkg.OdfElement;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import fr.opensagres.xdocreport.xhtml.extension.StringEscapeUtils;
import fr.opensagres.xdocreport.xhtml.extension.XHTMLConstants;
import fr.opensagres.xdocreport.xhtml.extension.XHTMLPageContentBuffer;
public class ElementVisitorForXHTML
extends ElementVisitorConverter
implements XHTMLConstants
{
private static final String _100 = "100%;";
private static final String CHARACTER = "character";
private static final String BLOCK = "block";
private String masterPageLayoutName = null;
private String currentMasterPageLayoutName = null;
private final ODFXHTMLPage xhtml;
private XHTMLPageContentBuffer currentXHTMLContent;
public ElementVisitorForXHTML( ODFXHTMLPage xhtml, XHTMLOptions options, OdfDocument odfDocument, OutputStream out,
Writer writer )
{
super( odfDocument, options != null ? options.getExtractor() : null, out, writer );
this.xhtml = xhtml;
this.currentXHTMLContent = null;
}
// ---------------------- visit root
// styles.xml//office:document-styles/office:master-styles
@Override
public void visit( OfficeMasterStylesElement ele )
{
super.visit( ele );
}
// ---------------------- visit root
// styles.xml//office:document-styles/office:master-styles/style:master-page
/**
* Generate XHTML page footer + header
*/
@Override
public void visit( StyleMasterPageElement ele )
{
currentMasterPageLayoutName = ele.getStylePageLayoutNameAttribute();
if ( masterPageLayoutName == null )
{
masterPageLayoutName = currentMasterPageLayoutName;
xhtml.getPageBeforeBody().setBodyClass( xhtml.getStyleEngine().getClassName( OdfStyleFamily.List.getName(),
masterPageLayoutName ) );
}
super.visit( ele );
}
// ---------------------- visit
// styles.xml//office:document-styles/office:master-styles/style:master-page/style-header
@Override
public void visit( StyleHeaderElement ele )
{
currentXHTMLContent = xhtml.getPageBodyContentHeader();
visitMasterPageHeaderFooter( ele,
xhtml.getStyleEngine().getMasterPageHeaderStyleName( currentMasterPageLayoutName ) );
}
// ---------------------- visit
// styles.xml//office:document-styles/office:master-styles/style:master-page/style-footer
@Override
public void visit( StyleFooterElement ele )
{
currentXHTMLContent = xhtml.getPageBodyContentFooter();
visitMasterPageHeaderFooter( ele,
xhtml.getStyleEngine().getMasterPageFooterStyleName( currentMasterPageLayoutName ) );
}
private void visitMasterPageHeaderFooter( OdfElement ele, String styleName )
{
String styleFamilyName = OdfStyleFamily.List.getName();
visit( DIV_ELEMENT, ele, styleName, styleFamilyName );
}
// ---------------------- visit root //office-body/office-text
@Override
public void visit( OfficeTextElement ele )
{
currentXHTMLContent = xhtml.getPageBodyContentBody();
// String styleName = masterPageLayoutName;
// String styleFamilyName = OdfStyleFamily.List.getName();
visit( DIV_ELEMENT, ele, null, null );
}
// ---------------------- visit //text:h
@Override
public void visit( TextHElement ele )
{
// Get level (Heading levels go only to 6 in XHTML)).
int level = 1;
Integer levelAsInteger = ele.getTextOutlineLevelAttribute();
if ( levelAsInteger != null && levelAsInteger <= 6 )
{
level = levelAsInteger;
}
visit( H_ELEMENT + level, ele );
}
// ---------------------- visit //text:p
@Override
public void visit( TextPElement ele )
{
boolean addNbsp = ele.getFirstChild() == null;
visit( P_ELEMENT, ele, addNbsp );
}
// ---------------------- visit //text:span
@Override
public void visit( TextSpanElement ele )
{
boolean addNbsp = ele.getFirstChild() == null;
visit( SPAN_ELEMENT, ele, addNbsp );
}
// ---------------------- visit //text:a
@Override
public void visit( TextAElement ele )
{
String href = ele.getXlinkHrefAttribute();
Collection attributes = new ArrayList();
attributes.add( HREF_ATTR );
attributes.add( href );
visit( A_ELEMENT, ele, attributes.toArray( StringUtils.EMPTY_STRING_ARRAY ) );
}
// ---------------------- visit text:list
@Override
public void visit( TextListElement ele )
{
int level = 1;
boolean numberedList = false;
String styleName = ele.getTextStyleNameAttribute();
if ( StringUtils.isNotEmpty( styleName ) )
{
try
{
OdfTextListStyle listStyle = odfDocument.getContentDom().getAutomaticStyles().getListStyle( styleName );
if ( listStyle != null )
{
TextListLevelStyleElementBase levelListStyle = listStyle.getLevel( level );
numberedList =
( levelListStyle != null && TextListLevelStyleNumberElement.ELEMENT_NAME.equals( levelListStyle.getOdfName() ) );
}
}
catch ( Exception e )
{
// Do nothing
}
}
String elementName = numberedList ? OL_ELEMENT : UL_ELEMENT;
startVisit( elementName, ele );
// String styleName = null;
// String styleFamilyName = "";
// currentXHTMLContent.getStyleEngine().applyStyles(styleName,
// styleFamilyName,
// xhtml);
endVisit( elementName, ele );
}
// ---------------------- visit text:listitem
@Override
public void visit( TextListItemElement ele )
{
visit( LI_ELEMENT, ele, null, null );
}
// ---------------------- visit table:table (ex : )
private List columnsWidth;
@Override
public void visit( TableTableElement ele )
{
try
{
columnsWidth = ODFUtils.getColumnWidthsAsString( ele, odfDocument );
visit( TABLE_ELEMENT, ele );
}
finally
{
if ( columnsWidth != null )
{
columnsWidth = null;
}
}
}
// ---------------------- visit table:table-column
@Override
public void visit( TableTableColumnElement ele )
{
String[] attributes = null;
OdfStyle style = ele.getAutomaticStyle();
if ( style != null )
{
Node node = null;
NodeList nodes = style.getChildNodes();
for ( int i = 0; i < nodes.getLength(); i++ )
{
node = nodes.item( i );
if ( StyleTableColumnPropertiesElement.ELEMENT_NAME.getLocalName().equals( node.getLocalName() ) )
{
StyleTableColumnPropertiesElement columnPropertiesElement =
(StyleTableColumnPropertiesElement) node;
// width
String width = columnPropertiesElement.getStyleRelColumnWidthAttribute();
if ( StringUtils.isEmpty( width ) )
{
width = columnPropertiesElement.getStyleColumnWidthAttribute();
}
if ( StringUtils.isNotEmpty( width ) )
{
attributes = new String[2];
attributes[0] = WIDTH_ATTR;
attributes[1] = ODFUtils.getDimensionAsPixel( width );
}
break;
}
}
}
Integer numberColumnsRepeated = ele.getTableNumberColumnsRepeatedAttribute();
if ( numberColumnsRepeated == null )
{
numberColumnsRepeated = 1;
}
for ( int i = 0; i < numberColumnsRepeated; i++ )
{
startVisit( COL_ELEMENT, ele, attributes );
endVisit( COL_ELEMENT, ele );
}
}
// ---------------------- visit table:table-row
private int cellIndex = -1;
@Override
public void visit( TableTableRowElement ele )
{
try
{
cellIndex = -1;
visit( TR_ELEMENT, ele );
}
finally
{
if ( cellIndex != -1 )
{
cellIndex = -1;
}
}
}
// ---------------------- visit table:table-cell
@Override
public void visit( TableTableCellElement ele )
{
Collection attributes = new ArrayList();
// table:number-columns-spanned
Integer colSpan = ele.getTableNumberColumnsSpannedAttribute();
if ( colSpan != null && colSpan != 1 )
{
attributes.add( COLSPAN_ATTR );
attributes.add( String.valueOf( colSpan ) );
}
// table:number-rows-spanned
Integer rowSpan = ele.getTableNumberRowsSpannedAttribute();
if ( rowSpan != null && rowSpan != 1 )
{
attributes.add( ROWSPAN_ATTR );
attributes.add( String.valueOf( rowSpan ) );
}
// // compute width
// cellIndex++;
// String width = null;
// if (columnsWidth != null && columnsWidth.size() > cellIndex) {
// String columnWidth = columnsWidth.get(cellIndex);
// // if (colSpan != null) {
// // columnWidth = columnWidth * colSpan;
// // }
// attributes.add(WIDTH_ATTR);
// attributes.add(String.valueOf(columnWidth));
// }
visit( TD_ELEMENT, ele, attributes.toArray( StringUtils.EMPTY_STRING_ARRAY ) );
}
// ---------------------- visit draw:frame
@Override
public void visit( DrawFrameElement ele )
{
// ex :
Collection attributes = new ArrayList();
// draw:name
String name = ele.getDrawNameAttribute();
if ( !StringUtils.isEmpty( name ) )
{
attributes.add( NAME_ATTR );
attributes.add( name );
}
StringBuilder htmlStyle = new StringBuilder();
// svg:x
String x = ele.getSvgXAttribute();
if ( !StringUtils.isEmpty( x ) )
{
htmlStyle.append( "left:" );
htmlStyle.append( x );
htmlStyle.append( ';' );
}
// svg:y
String y = ele.getSvgYAttribute();
if ( !StringUtils.isEmpty( y ) )
{
htmlStyle.append( "top:" );
htmlStyle.append( y );
htmlStyle.append( ';' );
}
// svg:width
String width = ele.getSvgWidthAttribute();
if ( !StringUtils.isEmpty( width ) )
{
htmlStyle.append( "width:" );
htmlStyle.append( width );
htmlStyle.append( ';' );
}
// svg:height
String height = ele.getSvgHeightAttribute();
if ( !StringUtils.isEmpty( height ) )
{
htmlStyle.append( "height:" );
htmlStyle.append( height );
htmlStyle.append( ';' );
}
// draw:z-index
Integer zIndex = ele.getDrawZIndexAttribute();
if ( zIndex != null )
{
htmlStyle.append( "z-index:" );
htmlStyle.append( String.valueOf( zIndex ) );
htmlStyle.append( ';' );
}
if ( htmlStyle.length() > 0 )
{
attributes.add( STYLE_ATTR );
attributes.add( htmlStyle.toString() );
}
visit( DIV_ELEMENT, ele, attributes.toArray( StringUtils.EMPTY_STRING_ARRAY ) );
}
// ---------------------- visit draw:image
@Override
protected void visitImage( DrawImageElement ele, String href, byte[] imageStream )
{
Collection attributes = new ArrayList();
// src
String src = ele.getXlinkHrefAttribute();
IURIResolver uriResolver = xhtml.getStyleEngine().getURIResolver();
src = uriResolver.resolve( src );
attributes.add( SRC_ATTR );
attributes.add( src );
// other attributes
Node parentNode = ele.getParentNode();
if ( parentNode instanceof DrawFrameElement )
{
DrawFrameElement frameElement = (DrawFrameElement) parentNode;
attributes.add( STYLE_ATTR );
StringBuilder styleAttr = new StringBuilder();
// width
styleAttr.append( WIDTH_ATTR );
styleAttr.append( ':' );
styleAttr.append( _100 );
// height
styleAttr.append( HEIGHT_ATTR );
styleAttr.append( ':' );
styleAttr.append( _100 );
String anchorType = frameElement.getTextAnchorTypeAttribute();
if ( !CHARACTER.equals( anchorType ) )
{
styleAttr.append( DISPLAY_ATTR );
styleAttr.append( ':' );
styleAttr.append( BLOCK );
}
attributes.add( styleAttr.toString() );
}
visit( IMG_ELEMENT, ele, null, null, attributes.toArray( StringUtils.EMPTY_STRING_ARRAY ) );
}
// ---------------------- visit text:line-break
@Override
public void visit( TextLineBreakElement ele )
{
currentXHTMLContent.startEndElement( BR_ELEMENT );
}
private void visit( String elementName, OdfStylableElement ele, String... attributes )
{
visit( elementName, ele, false, attributes );
}
private void visit( String elementName, OdfStylableElement ele, boolean addNbsp, String... attributes )
{
String styleName = ele.getStyleName();
String styleFamily = ele.getStyleFamily() != null ? ele.getStyleFamily().getName() : null;
visit( elementName, ele, addNbsp, styleName, styleFamily, attributes );
}
private void visit( String elementName, OdfElement ele, String styleName, String styleFamily, String... attributes )
{
visit( elementName, ele, false, styleName, styleFamily, attributes );
}
private void visit( String elementName, OdfElement ele, boolean addNbsp, String styleName, String styleFamily,
String... attributes )
{
startVisit( elementName, ele, attributes );
xhtml.getStyleEngine().applyStyles( styleFamily, styleName, currentXHTMLContent );
endVisit( elementName, ele, addNbsp );
}
private void startVisit( String elementName, OdfElement element, String... attributes )
{
currentXHTMLContent.startElementNotEnclosed( elementName );
if ( attributes != null )
{
String value = null;
String name = null;
for ( int i = 0; i < attributes.length; i++ )
{
String attr = attributes[i];
if ( i % 2 == 0 )
{
// Attribute name
name = attr;
}
else
{
// Attribute value
value = attr;
currentXHTMLContent.setAttribute( name, value );
name = null;
value = null;
}
}
}
}
private void endVisit( String elementName, OdfElement element )
{
endVisit( elementName, element, false );
}
private void endVisit( String elementName, OdfElement element, boolean addNbsp )
{
currentXHTMLContent.endElementNotEnclosed();
super.visit( element );
if ( addNbsp )
{
currentXHTMLContent.setText( " " );
}
currentXHTMLContent.endElement( elementName );
}
@Override
public void save()
throws IOException
{
if ( writer != null )
{
xhtml.save( writer );
}
else
{
xhtml.save( out );
}
super.save();
}
@Override
protected void processTextNode( Text node )
{
String content = node.getTextContent();
if ( StringUtils.isNotEmpty( content ) )
{
// Escape with HTML characters
currentXHTMLContent.setText( StringEscapeUtils.escapeHtml( content ) );
}
else
{
currentXHTMLContent.setText( " " );
}
}
}