| /***************************************************************************** |
| * 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; |
| } |
| |
| } |