/*
 *  ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one or more
 *    contributor license agreements.  See the NOTICE file distributed with
 *    this work for additional information regarding copyright ownership.
 *    The ASF licenses this file to You under the Apache License, Version 2.0
 *    (the "License"); you may not use this file except in compliance with
 *    the License.  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 * ====================================================================
 */

package org.apache.poi.examples.xwpf.usermodel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

/**
 * Tests whether it is possible to successfully update an Excel workbook that is
 * embedded into a WordprocessingML document. Note that the test has currently
 * only been conducted with a binary Excel workbook and NOT yet with a
 * SpreadsheetML workbook embedded into the document.<p>
 *
 * This code was successfully tested with the following file from the POI test collection:
 * http://svn.apache.org/repos/asf/poi/trunk/test-data/document/EmbeddedDocument.docx
 */
@SuppressWarnings({"java:S106","java:S4823","java:S1192"})
public class UpdateEmbeddedDoc {

    private XWPFDocument doc;
    private File docFile;

    private static final int SHEET_NUM = 0;
    private static final int ROW_NUM = 0;
    private static final int CELL_NUM = 0;
    private static final double NEW_VALUE = 100.98D;
    private static final String BINARY_EXTENSION = "xls";
    private static final String OPENXML_EXTENSION = "xlsx";

    /**
     * Create a new instance of the UpdateEmbeddedDoc class using the following
     * parameters;
     *
     * @param filename An instance of the String class that encapsulates the name
     *                 of and path to a WordprocessingML Word document that contains an
     *                 embedded binary Excel workbook.
     * @throws java.io.FileNotFoundException Thrown if the file cannot be found
     *                                       on the underlying file system.
     * @throws java.io.IOException           Thrown if a problem occurs in the underlying
     *                                       file system.
     */
    public UpdateEmbeddedDoc(String filename) throws FileNotFoundException, IOException {
        this.docFile = new File(filename);
        if (!this.docFile.exists()) {
            throw new FileNotFoundException("The Word document " + filename + " does not exist.");
        }
        try (FileInputStream fis = new FileInputStream(this.docFile)) {
            // Open the Word document file and instantiate the XWPFDocument class.
            this.doc = new XWPFDocument(fis);
        }
    }

    /**
     * Called to update the embedded Excel workbook. As the format and structure
     * of the workbook are known in advance, all this code attempts to do is
     * write a new value into the first cell on the first row of the first
     * worksheet. Prior to executing this method, that cell will contain the
     * value 1.
     *
     * @throws org.apache.poi.openxml4j.exceptions.OpenXML4JException
     *                             Rather
     *                             than use the specific classes (HSSF/XSSF) to handle the embedded
     *                             workbook this method uses those defined in the SS stream. As
     *                             a result, it might be the case that a SpreadsheetML file is
     *                             opened for processing, throwing this exception if that file is
     *                             invalid.
     * @throws java.io.IOException Thrown if a problem occurs in the underlying
     *                             file system.
     */
    public void updateEmbeddedDoc() throws OpenXML4JException, IOException {
        List<PackagePart> embeddedDocs = this.doc.getAllEmbeddedParts();
        for (PackagePart pPart : embeddedDocs) {
            String ext = pPart.getPartName().getExtension();
            if (BINARY_EXTENSION.equals(ext) || OPENXML_EXTENSION.equals(ext)) {
                // Get an InputStream from the package part and pass that
                // to the create method of the WorkbookFactory class. Update
                // the resulting Workbook and then stream that out again
                // using an OutputStream obtained from the same PackagePart.
                try (InputStream is = pPart.getInputStream();
                     Workbook workbook = WorkbookFactory.create(is);
                     OutputStream os = pPart.getOutputStream()) {
                    Sheet sheet = workbook.getSheetAt(SHEET_NUM);
                    Row row = sheet.getRow(ROW_NUM);
                    Cell cell = row.getCell(CELL_NUM);
                    cell.setCellValue(NEW_VALUE);
                    workbook.write(os);
                }
            }
        }

        if (!embeddedDocs.isEmpty()) {
            // Finally, write the newly modified Word document out to file.
            try (FileOutputStream fos = new FileOutputStream(this.docFile)) {
                this.doc.write(fos);
            }
        }
    }

    /**
     * Called to test whether or not the embedded workbook was correctly
     * updated. This method simply recovers the first cell from the first row
     * of the first workbook and tests the value it contains.
     * <p>
     * Note that execution will not continue up to the assertion as the
     * embedded workbook is now corrupted and causes an IllegalArgumentException
     * with the following message
     * <p>
     * <em>java.lang.IllegalArgumentException: Your InputStream was neither an
     * OLE2 stream, nor an OOXML stream</em>
     * <p>
     * to be thrown when the WorkbookFactory.createWorkbook(InputStream) method
     * is executed.
     *
     * @throws org.apache.poi.openxml4j.exceptions.OpenXML4JException
     *                             Rather
     *                             than use the specific classes (HSSF/XSSF) to handle the embedded
     *                             workbook this method uses those defined in the SS stream. As
     *                             a result, it might be the case that a SpreadsheetML file is
     *                             opened for processing, throwing this exception if that file is
     *                             invalid.
     * @throws java.io.IOException Thrown if a problem occurs in the underlying
     *                             file system.
     */
    public void checkUpdatedDoc() throws OpenXML4JException, IOException {
        for (PackagePart pPart : this.doc.getAllEmbeddedParts()) {
            String ext = pPart.getPartName().getExtension();
            if (BINARY_EXTENSION.equals(ext) || OPENXML_EXTENSION.equals(ext)) {
                try (InputStream is = pPart.getInputStream();
                     Workbook workbook = WorkbookFactory.create(is)) {
                    Sheet sheet = workbook.getSheetAt(SHEET_NUM);
                    Row row = sheet.getRow(ROW_NUM);
                    Cell cell = row.getCell(CELL_NUM);
                    if(cell.getNumericCellValue() != NEW_VALUE) {
                        throw new IllegalStateException("Failed to validate document content.");
                    }
                }
            }
        }
    }

    /**
     * Code to test updating of the embedded Excel workbook.
     */
    public static void main(String[] args) throws IOException, OpenXML4JException {
        UpdateEmbeddedDoc ued = new UpdateEmbeddedDoc(args[0]);
        ued.updateEmbeddedDoc();
        ued.checkUpdatedDoc();
    }
}
