Package org.odftoolkit.odfdom.pkg

Source Code of org.odftoolkit.odfdom.pkg.EmbeddedDocumentTest

/************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
*
* Use is subject to license terms.
*
* Licensed 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. You can also
* obtain a copy of the License at http://odftoolkit.org/docs/license.txt
*
* 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.odftoolkit.odfdom.pkg;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;

import org.junit.Assert;
import org.junit.Test;
import org.odftoolkit.odfdom.doc.OdfDocument;
import org.odftoolkit.odfdom.doc.OdfSpreadsheetDocument;
import org.odftoolkit.odfdom.doc.OdfTextDocument;
import org.odftoolkit.odfdom.doc.OdfDocument.OdfMediaType;
import org.odftoolkit.odfdom.doc.table.OdfTable;
import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
import org.odftoolkit.odfdom.dom.attribute.text.TextAnchorTypeAttribute;
import org.odftoolkit.odfdom.dom.element.draw.DrawObjectElement;
import org.odftoolkit.odfdom.dom.element.text.TextHElement;
import org.odftoolkit.odfdom.dom.element.text.TextPElement;
import org.odftoolkit.odfdom.incubator.doc.draw.OdfDrawFrame;
import org.odftoolkit.odfdom.incubator.doc.text.OdfTextSpan;
import org.odftoolkit.odfdom.pkg.manifest.OdfFileEntry;
import org.odftoolkit.odfdom.utils.ResourceUtilities;
import org.w3c.dom.NodeList;

public class EmbeddedDocumentTest {

  private static final Logger LOG = Logger.getLogger(EmbeddedDocumentTest.class.getName());
  private static final String TEST_FILE_FOLDER = ResourceUtilities.getTestOutputFolder();
  private static final String TEST_FILE_EMBEDDED = "performance/Presentation1_INVALID.odp";
  private static final String TEST_FILE_EMBEDDED_SAVE_OUT = "SaveEmbeddedDoc.odt";
  private static final String TEST_FILE_EMBEDDED_SIDEBYSIDE_SAVE_OUT = "SaveEmbeddedDocSideBySide.odt";
  private static final String TEST_FILE_EMBEDDED_INCLUDED_SAVE_OUT = "SaveEmbeddedDocIncluded.odt";
  private static final String TEST_FILE_REMOVE_EMBEDDED_SAVE_OUT = "RemoveEmbeddedDoc.odt";
  private static final String TEST_FILE_MODIFIED_EMBEDDED = "TestModifiedEmbeddedDoc.odt";
  private static final String TEST_FILE_MODIFIED_EMBEDDED_SAVE_STANDALONE = "SaveModifiedEmbeddedDocAlone.odt";
  private static final String TEST_SPAN_TEXT = "Modify Header";
  private static final String TEST_PIC = "testA.jpg";
  private static final String TEST_PIC_ANOTHER = "testB.jpg";
  private static final String SLASH = "/";

  /**
   * The document A contains the embedded document E1,
   * this test case is used to embed E1 to another document B
   */
  @Test
  public void testEmbedEmbeddedDocument() {
    try {
      OdfDocument doc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE_EMBEDDED));
      OdfDocument saveDoc = OdfTextDocument.newTextDocument();
      Map<String, OdfDocument> subDocs = doc.loadSubDocuments();
      List<String> subDocNames = new ArrayList<String>();
      for (String childDocPath : subDocs.keySet()) {
        OdfDocument childDoc = subDocs.get(childDocPath);
        String embeddedDocPath = childDoc.getDocumentPath();
        saveDoc.insertDocument(childDoc, embeddedDocPath);
        subDocNames.add(embeddedDocPath);
      }
      Set<String> paths = saveDoc.getPackage().getDocumentPaths();
      int docCount = paths.size();
      paths = saveDoc.getPackage().getDocumentPaths("application/vnd.oasis.opendocument.presentation");
      int presentationDocCount = paths.size();
      Assert.assertTrue(docCount > presentationDocCount);
      saveDoc.save(TEST_FILE_FOLDER + TEST_FILE_EMBEDDED_SAVE_OUT);
      saveDoc.close();
      saveDoc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE_EMBEDDED_SAVE_OUT));
      Map<String, OdfDocument> reloadedSubDocs = saveDoc.loadSubDocuments();
      Assert.assertTrue(subDocs.size() == reloadedSubDocs.size());
      for (String childDocPath : subDocs.keySet()) {
        Assert.assertEquals(subDocs.get(childDocPath).getMediaTypeString(), reloadedSubDocs.get(childDocPath).getMediaTypeString());
      }
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
      Assert.fail("Failed to embed an embedded Document: '" + ex.getMessage() + "'");
    }
  }

  /**
   * The document B is embedded to document A
   * and the directory path of A and B are absolute from the package
   * DOCA/ and DOCB/
   */
  @Test
  public void testembeddedDocumentsLocatedSideBySide() {
    try {
      OdfTextDocument odtRootDoc = OdfTextDocument.newTextDocument();
      odtRootDoc.insertDocument(OdfTextDocument.newTextDocument(), "DOCA/");
      OdfDocument docA = odtRootDoc.loadSubDocument("DOCA");
      docA.newImage(ResourceUtilities.getURI(TEST_PIC));
      docA.insertDocument(OdfSpreadsheetDocument.newSpreadsheetDocument(), "../DOCB/");
      OdfFileDom contentA = docA.getContentDom();
      XPath xpath = contentA.getXPath();
      TextPElement lastPara = (TextPElement) xpath.evaluate("//text:p[last()]", contentA, XPathConstants.NODE);
      addFrameForEmbeddedDoc(contentA, lastPara, "DOCB");
      OdfDocument docB = odtRootDoc.loadSubDocument("DOCB/");
      Assert.assertNotNull(docB);
      Assert.assertNull(odtRootDoc.loadSubDocument("DOCA/DOCB/"));
      docB.newImage(ResourceUtilities.getURI(TEST_PIC_ANOTHER));
      OdfTable table1 = docB.getTableList().get(0);
      table1.setTableName("NewTable");
      updateFrameForEmbeddedDoc(contentA, "./DOCB", "DOCA/DOCB");
      //if user want to save the docA with the side by side embedded document
      //he has to insert it to the sub document of docA and update the xlink:href link
      docA.insertDocument(docB, "DOCB/");
      //save
      docA.save(TEST_FILE_FOLDER + TEST_FILE_EMBEDDED_SIDEBYSIDE_SAVE_OUT);
      OdfDocument testLoad = OdfDocument.loadDocument(TEST_FILE_FOLDER + TEST_FILE_EMBEDDED_SIDEBYSIDE_SAVE_OUT);
      OdfFileEntry imageEntry = testLoad.getPackage().getFileEntry(OdfPackage.OdfFile.IMAGE_DIRECTORY.getPath() + SLASH + TEST_PIC);
      Assert.assertNotNull(imageEntry);
      Map<String, OdfDocument> embDocs = testLoad.loadSubDocuments(OdfDocument.OdfMediaType.SPREADSHEET);
      for(String embedDocPath : embDocs.keySet()){
        OdfDocument doc1 = embDocs.get(embedDocPath);
        imageEntry = doc1.getPackage().getFileEntry(doc1.getDocumentPath() + OdfPackage.OdfFile.IMAGE_DIRECTORY.getPath() + SLASH + TEST_PIC_ANOTHER);
        Assert.assertNotNull(doc1.getTableByName("NewTable"));
      }
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
      Assert.fail("Failed with " + ex.getClass().getName() + ": '" + ex.getMessage() + "'");
    }
  }

  /**
   * 1) A new sub document text document DOCA/ is inserted into a new text document
   * 2) A picture is being added to the subdocument (ie. /DOCA/Pictures/testA.jpg)
   * 3) A new sub document spreadsheet document is inserted into the first (ie. /DOCA/DOCB)
   * 4) In the last paragraph of /DOCA a frame with a reference to the subdocument DOCB is added
   * 5) A picture is being added to the second subdocument (ie. /DOCA/DOCB/Pictures/testB.jpg)
   * 6) The spreadsheetname of DOCB is set to "NewTable"
   * 7) DOCA/ is saved in a document for its own  
   */
  @Test
  public void testembeddedDocumentWithSubPath() {
    try {
      OdfTextDocument odtDoc1 = OdfTextDocument.newTextDocument();
      odtDoc1.insertDocument(OdfTextDocument.newTextDocument(), "DOCA/");
      OdfDocument docA = odtDoc1.loadSubDocument("DOCA");
      docA.newImage(ResourceUtilities.getURI(TEST_PIC));
      docA.insertDocument(OdfSpreadsheetDocument.newSpreadsheetDocument(), "DOCB/");
      OdfFileDom contentA = docA.getContentDom();
      XPath xpath = contentA.getXPath();
      TextPElement lastPara = (TextPElement) xpath.evaluate("//text:p[last()]", contentA, XPathConstants.NODE);
      addFrameForEmbeddedDoc(contentA, lastPara, "./DOCB");
      OdfDocument docB = odtDoc1.loadSubDocument("DOCA/DOCB/");
      docB.newImage(ResourceUtilities.getURI(TEST_PIC_ANOTHER));
      OdfTable table1 = docB.getTableList().get(0);
      table1.setTableName("NewTable");
      Assert.assertNotNull(docB);
      Assert.assertNull(odtDoc1.loadSubDocument("DOCB/"));
      docA.save(TEST_FILE_FOLDER + TEST_FILE_EMBEDDED_INCLUDED_SAVE_OUT);
      OdfDocument testLoad = OdfDocument.loadDocument(TEST_FILE_FOLDER + TEST_FILE_EMBEDDED_INCLUDED_SAVE_OUT);
      OdfFileEntry imageEntry = testLoad.getPackage().getFileEntry(OdfPackage.OdfFile.IMAGE_DIRECTORY.getPath() + SLASH + TEST_PIC);
      Assert.assertNotNull(imageEntry);
      Map<String, OdfDocument> embDocs = testLoad.loadSubDocuments(OdfDocument.OdfMediaType.SPREADSHEET);
      for (String childDocPath : embDocs.keySet()) { 
        OdfDocument doc1 = embDocs.get(childDocPath);
        imageEntry = doc1.getPackage().getFileEntry(doc1.getDocumentPath() + OdfPackage.OdfFile.IMAGE_DIRECTORY.getPath() + SLASH + TEST_PIC_ANOTHER);
        Assert.assertNotNull(doc1.getTableByName("NewTable"));
      }
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
      Assert.fail("Failed with " + ex.getClass().getName() + ": '" + ex.getMessage() + "'");
    }
  }

  /**
   * The document A contains the embedded document E1,
   * This test case is used to show how to save the E1 to a stand alone document.
   */
  @Test
  public void testSaveEmbeddedDocument() {
    try {
      OdfDocument doc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE_EMBEDDED));
      Map<String, OdfDocument> embeddedDocs = doc.loadSubDocuments();
      for (String childDocPath : embeddedDocs.keySet()) {
        OdfDocument childDoc = embeddedDocs.get(childDocPath);
        String embedFileName = childDoc.getDocumentPath();
        OdfMediaType embedMediaType = OdfMediaType.getOdfMediaType(childDoc.getMediaTypeString());
        //use '_' replace '/', because '/' is not the valid char in file path
        embedFileName = embedFileName.replaceAll("/", "_") + "." + embedMediaType.getSuffix();
        childDoc.save(TEST_FILE_FOLDER + embedFileName);
        LOG.log(Level.INFO, "Save file : {0}", TEST_FILE_FOLDER + embedFileName);
        OdfDocument embeddedDoc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(embedFileName));
        Assert.assertEquals(embeddedDoc.getMediaTypeString(), embedMediaType.getMediaTypeString());
      }
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
      Assert.fail("Failed with " + ex.getClass().getName() + ": '" + ex.getMessage() + "'");
    }

  }

  /**
   * There are two document, one is Presentation1_INVALID.odp
   * another is a new text document TestModifiedEmbeddedDoc.odt
   * Presentation1_INVALID.odp contains an embed document named "Object 1/", add one paragraph to Object 1
   * then embed "Object 1" to the new text document, and save this text document
   * reload TestModifiedEmbeddedDoc.odt, then get and modify embed document "DocA" and save it to a standalone document
   * load the saved standalone document, and check the content of it
   */
  @Test
  public void testEmbedModifiedEmbeddedDocument() {
    try {
      OdfDocument doc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE_EMBEDDED));
      OdfDocument saveDoc = OdfTextDocument.newTextDocument();
      OdfDocument embeddedDoc = doc.loadSubDocument("Object 1/");
      //modify content of "Object 1"
      OdfFileDom embedContentDom = embeddedDoc.getContentDom();
      XPath xpath = embedContentDom.getXPath();
      TextHElement header = (TextHElement) xpath.evaluate("//text:h[1]", embedContentDom, XPathConstants.NODE);
      LOG.log(Level.INFO, "First para: {0}", header.getTextContent());
      OdfTextSpan spanElem = new OdfTextSpan(embedContentDom);
      spanElem.setTextContent(TEST_SPAN_TEXT);
      header.appendChild(spanElem);
      //insert image to "Object 1"
      embeddedDoc.newImage(ResourceUtilities.getURI(TEST_PIC));
      //embed "Object 1" to TestModifiedEmbeddedDoc.odt as the path /DocA
      String embedPath = "DocA";
      saveDoc.insertDocument(embeddedDoc, embedPath);
      saveDoc.save(TEST_FILE_FOLDER + TEST_FILE_MODIFIED_EMBEDDED);
      saveDoc.close();
      //reload TestModifiedEmbeddedDoc.odt
      saveDoc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE_MODIFIED_EMBEDDED));
      embeddedDoc = saveDoc.loadSubDocument(embedPath);
      //check the content of "DocA" and modify it again
      embedContentDom = embeddedDoc.getContentDom();
      header = (TextHElement) xpath.evaluate("//text:h[1]", embedContentDom, XPathConstants.NODE);
      Assert.assertTrue(header.getTextContent().contains(TEST_SPAN_TEXT));
      header.setTextContent("");
      String packagePath = embeddedDoc.getDocumentPath() + SLASH + OdfPackage.OdfFile.IMAGE_DIRECTORY.getPath() + SLASH + TEST_PIC;
      OdfFileEntry imageEntry = embeddedDoc.getPackage().getFileEntry(packagePath);
      Assert.assertNotNull(imageEntry);
      embeddedDoc.newImage(ResourceUtilities.getURI(TEST_PIC_ANOTHER));
      //save the "DocA" as the standalone document
      embeddedDoc.save(TEST_FILE_FOLDER + TEST_FILE_MODIFIED_EMBEDDED_SAVE_STANDALONE);
      //load the standalone document and check the content
      OdfDocument standaloneDoc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE_MODIFIED_EMBEDDED_SAVE_STANDALONE));
      embedContentDom = standaloneDoc.getContentDom();
      header = (TextHElement) xpath.evaluate("//text:h[1]", embedContentDom, XPathConstants.NODE);
      Assert.assertTrue(header.getTextContent().length() == 0);
      imageEntry = standaloneDoc.getPackage().getFileEntry(OdfPackage.OdfFile.IMAGE_DIRECTORY.getPath() + SLASH + TEST_PIC);
      Assert.assertNotNull(imageEntry);
      OdfFileEntry anotherImageEntry = standaloneDoc.getPackage().getFileEntry(OdfPackage.OdfFile.IMAGE_DIRECTORY.getPath() + SLASH + TEST_PIC_ANOTHER);
      Assert.assertNotNull(anotherImageEntry);
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
      Assert.fail("Failed with " + ex.getClass().getName() + ": '" + ex.getMessage() + "'");
    }
  }

  @Test
  public void testRemoveEmbeddedDocument() {
    try {
      OdfDocument doc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE_EMBEDDED));
      Map<String, OdfDocument> embeddedDocs = doc.loadSubDocuments();
      List<String> subDocNames = new ArrayList<String>();
      for (String childDocPath : embeddedDocs.keySet()) {
        OdfDocument childDoc = embeddedDocs.get(childDocPath);
        Assert.assertNotNull(childDoc);
        String embedFileName = childDoc.getDocumentPath();
        subDocNames.add(embedFileName);
        doc.removeDocument(embedFileName);
      }
      doc.save(TEST_FILE_FOLDER + TEST_FILE_REMOVE_EMBEDDED_SAVE_OUT);
      doc.close();
      //check manifest entry for the embed document
      //the sub entry of the embed document such as the pictures of the document should also be removed
      doc = OdfDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE_REMOVE_EMBEDDED_SAVE_OUT));
      Map<String, OdfDocument> reloadedSubDocs = doc.loadSubDocuments();
      Assert.assertTrue(0 == reloadedSubDocs.size());
      Set<String> entries = doc.getPackage().getFilePaths();
      Iterator<String> entryIter = null;
      for (int i = 0; i < subDocNames.size(); i++) {
        entryIter = entries.iterator();
        String embeddedDocPath = subDocNames.get(i);
        while (entryIter.hasNext()) {
          String entry = entryIter.next();
          Assert.assertFalse(entry.startsWith(embeddedDocPath));
        }
      }
      doc.close();
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
      Assert.fail("Failed with " + ex.getClass().getName() + ": '" + ex.getMessage() + "'");
    }
  }

  private void addFrameForEmbeddedDoc(OdfFileDom dom, TextPElement para, String path) throws Exception {
    OdfDrawFrame drawFrame = new OdfDrawFrame(dom);
    drawFrame.setDrawNameAttribute(path);
    drawFrame.setTextAnchorTypeAttribute(TextAnchorTypeAttribute.Value.PARAGRAPH.toString());
    drawFrame.setSvgXAttribute("0.834cm");
    drawFrame.setSvgYAttribute("2.919cm");
    drawFrame.setSvgWidthAttribute("13.257cm");
    drawFrame.setSvgHeightAttribute("11.375cm");
    drawFrame.setDrawZIndexAttribute(0);

    DrawObjectElement object = new DrawObjectElement(dom);

    object.setXlinkHrefAttribute(path);
    object.setXlinkActuateAttribute("onLoad");
    object.setXlinkShowAttribute("embed");
    object.setXlinkTypeAttribute("simple");
    drawFrame.appendChild(object);
    para.appendChild(drawFrame);
  }

  private void updateFrameForEmbeddedDoc(OdfFileDom dom, String originPath, String newPath) throws Exception {
    NodeList objNodes = dom.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "object");
    for (int i = 0; i < objNodes.getLength(); i++) {
      OdfElement object = (OdfElement) objNodes.item(i);
      String refObjPath = object.getAttributeNS(OdfDocumentNamespace.XLINK.getUri(), "href");
      if (refObjPath.equals(originPath)) {
        object.setAttributeNS(OdfDocumentNamespace.XLINK.getUri(), "href", newPath);
      }
    }
  }
}
TOP

Related Classes of org.odftoolkit.odfdom.pkg.EmbeddedDocumentTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.