blob: 4e973c950fbac89208bb83670b974d986b53e066 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2017 Atos.
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Mohamed Ali Bach Tobji (Atos) mohamed-ali.bachtobji@atos.net - Initial API and implementation
*****************************************************************************/
package org.eclipse.gendoc.services.docx;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.emf.common.util.EList;
import org.eclipse.gendoc.documents.AbstractTableService;
import org.eclipse.gendoc.documents.IDocumentService;
import org.eclipse.gendoc.services.exception.InvalidContentException;
import org.eclipse.gendoc.tags.ITag;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.eclipse.gendoc.table.Cell;
import org.eclipse.gendoc.table.Row;
import org.eclipse.gendoc.table.Table;
public class DOCXTableService extends AbstractTableService {
/*
*
* @see
* org.eclipse.gendoc.documents.ITableService#manageTable(org.eclipse.gendoc
* .tags.ITag, org.eclipse.gendoc.documents.IDocumentService,
* java.lang.StringBuffer, java.lang.Object, org.w3c.dom.Node)
*/
public String manageTable(ITag tag, IDocumentService documentService, StringBuffer returnValue, Object tableModel,
Node tableNode) throws InvalidContentException {
Node mainTable = tableNode.getFirstChild();
if (documentService.isTable(mainTable.getNodeName())) {
if (tableModel instanceof Table) {
// extract width of the table to generate
String wdth = getChildNode("w:gridCol", getChildNode("w:tblGrid", mainTable)).getAttributes()
.getNamedItem("w:w").getNodeValue();
Node rowNode = getChildNode(documentService.getRowLabel(), mainTable);
String rowLabel = documentService.getRowLabel();
/**
* FIXME find a better way to get the row label index
*/
Pattern rowPattern = Pattern.compile("<" + rowLabel + "[^<>]*>.*</" + rowLabel + ">");
Matcher rowm = rowPattern.matcher(returnValue);
int index_row_start = 0;
int index_row_end = 0;
if (rowm.find()) {
index_row_start = rowm.start();
index_row_end = returnValue.lastIndexOf("</" + rowLabel + ">");
String row = returnValue.substring(index_row_start, index_row_end + rowLabel.length() + 3);
String colLabel = documentService.getCellLabel();
int index_col_start = row.lastIndexOf("<" + colLabel + ">");
int index_col_end = row.lastIndexOf("</" + colLabel + ">");
Node colNode = getChildNode(documentService.getCellLabel(), rowNode);
int nbCol = ((Table) tableModel).getColCount();
int colWidth = Math.round(Integer.parseInt(wdth) / nbCol);
getChildNode("w:tcW", getChildNode("w:tcPr", colNode)).getAttributes().getNamedItem("w:w")
.setNodeValue(String.valueOf(colWidth));
StringBuffer colNodetxt = new StringBuffer(documentService.asText(colNode));
String txtLabel = "w:p";
String txtstyleLabel = "w:rPr";
Pattern txtPattern = Pattern.compile("<" + txtLabel + "[^<>]*>.*</" + txtLabel + ">");
Pattern txtstylePattern = Pattern
.compile("<" + txtstyleLabel + "[^<>]*>.*</" + txtstyleLabel + ">");
Matcher txtm = txtPattern.matcher(colNodetxt);
Matcher txtstylem = txtstylePattern.matcher(colNodetxt);
if (txtm.find()) {
String style = "";
if (txtstylem.find()) {
style = colNodetxt.substring(txtstylem.start(),
txtstylem.end() + txtstyleLabel.length() + 3);
}
return generateTable(returnValue, tableModel, rowLabel, index_row_start, index_row_end, row,
colLabel, index_col_start, index_col_end, colNodetxt, txtm, style, txtLabel);
}
}
}
}
return null;
}
/**
* Get a node from the parent node given as parameter
*
* @param label
* of the node to fetch
* @param parentnode
* @return
*/
private Node getChildNode(String label, Node parentnode) {
NodeList rowChildNodes = parentnode.getChildNodes();
for (int i = 0; i < rowChildNodes.getLength(); i++) {
Node current = rowChildNodes.item(i);
if (current.getNodeName() == label) {
return current;
}
}
return null;
}
/**
* Generates the table
*
* @param returnValue
* @param tableModel
* @param rowLabel
* @param index_row_start
* @param index_row_end
* @param row
* @param colLabel
* @param index_col_start
* @param index_col_end
* @param colNodetxt
* @param txtm
* @param rows
* @param style
* @param txtLabel
* @return
*/
private String generateTable(StringBuffer returnValue, Object tableModel, String rowLabel, int index_row_start,
int index_row_end, String row, String colLabel, int index_col_start, int index_col_end,
StringBuffer colNodetxt, Matcher txtm, String style, String txtLabel) {
String rows = "";
String cells = "";
// generate table header
StringBuffer newRow = new StringBuffer(row);
cells = generateCells(((Table) tableModel).getTableheader().getCells(), colNodetxt, txtm, style, txtLabel);
newRow.replace(index_col_start, index_col_end + colLabel.length() + 3, cells);
rows += newRow.toString();
// generate table body
for (Row r : ((Table) tableModel).getRows()) {
newRow = new StringBuffer(row);
cells = generateCells(r.getCells(), colNodetxt, txtm, style, txtLabel);
newRow.replace(index_col_start, index_col_end + colLabel.length() + 3, cells);
rows += newRow.toString();
}
return returnValue.replace(index_row_start, index_row_end + rowLabel.length() + 3, rows).toString();
}
/**
* Generates a row
*
* @param modelCells
* @param colNodetxt
* @param txtm
* @param style
* @param txtLabel
* @param cols
* @return
*/
private String generateCells(EList<Cell> modelCells, StringBuffer colNodetxt, Matcher txtm, String style,
String txtLabel) {
String cols = "";
for (Cell cell : modelCells) {
StringBuffer newCol;
int txtindex = txtm.end() - txtLabel.length() - 3;
newCol = new StringBuffer(colNodetxt.toString());
newCol.insert(txtindex, "<w:r>" + style + "<w:t>" + cell.getLabel() + "</w:t></w:r>");
cols += newCol.toString();
}
return cols;
}
}