corinthia-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pmke...@apache.org
Subject [66/92] [abbrv] incubator-corinthia git commit: Implement DFGet, DFPut, and DFCreate
Date Wed, 17 Dec 2014 13:29:16 GMT
Implement DFGet, DFPut, and DFCreate

These three functions implement the top-level entry points to the key
bidirectional transformation operations on documents. Compared to the
DF{Get,Put,Create}File functions, they allow for more custom usage.
Instead of requiring the concrete and abstract documents to be stored in
a file, they can be stored in various other means, as supported by the
DFConcreteDocument and DFAbstractDocument class.

One example of where you might want to avoid filesystem storage of
documents is when creating an abstract document purely for the purposes
of making some changes to it and then doing a put operation to update
the original. Where it was previously necessary to create a temporary
file for the conversion, it can now be done entirely in memory, using
packages created by DFPackageNewMemory().

Another example is the automated tests, which create an in-memory
representation of a document based on a plain text format, and avoid
writing temporary files to disk during test runs. While these functions
presently still call the Word-specific conversion functions directly,
they will shortly be modified to use DFGet, DFPut, and DFCreate.

The DFGetFile, DFPutFile, and DFCreateFile are now wrappers around their
more generic counterparts. They construct a DFConcreteDocument and
DFAbstractDocument, and then pass those to the wrapped functions. They
can be considered a useful illustration of how to use the API, in that
they operate at a higher level of abstraction, but are done entirely in
terms of the lower level of abstraction of DFGet, DFPut, and DFCreate.

We also now have the basic infrastructure in place for easily handling
different concrete document formats. There is a switch statement in each
of these formats which checks which format the document is stored in,
and then dispatches to a get, put, or create function specific to that
format. Currently the only supported format is .docx, but others can be
added by implementing versions of these functions and adding them to the
switch statements. We may even choose use an "interface" (in C, a struct
containing function pointers) to record the implementations of these
operations for each supported file format.


Project: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/commit/ef86c301
Tree: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/tree/ef86c301
Diff: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/diff/ef86c301

Branch: refs/heads/stable
Commit: ef86c30121da86e106e0112389d40891ed875cbf
Parents: 4f74168
Author: Peter Kelly <peter@uxproductivity.com>
Authored: Sat Dec 6 02:04:13 2014 +0700
Committer: Peter Kelly <peter@uxproductivity.com>
Committed: Sat Dec 6 02:04:13 2014 +0700

----------------------------------------------------------------------
 DocFormats/api/headers/DocFormats/Operations.h |  12 +-
 DocFormats/api/src/Operations.c                | 346 ++++++++++----------
 DocFormats/filters/ooxml/src/word/Word.c       | 104 ++++++
 DocFormats/filters/ooxml/src/word/Word.h       |   5 +
 4 files changed, 282 insertions(+), 185 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/ef86c301/DocFormats/api/headers/DocFormats/Operations.h
----------------------------------------------------------------------
diff --git a/DocFormats/api/headers/DocFormats/Operations.h b/DocFormats/api/headers/DocFormats/Operations.h
index 8574542..192cb80 100644
--- a/DocFormats/api/headers/DocFormats/Operations.h
+++ b/DocFormats/api/headers/DocFormats/Operations.h
@@ -18,12 +18,6 @@
 #include "DFError.h"
 #include "DFPackage.h"
 
-// Abstraction level 1
-
-int DFGetFile(const char *concrete, const char *abstract, DFError **error);
-int DFPutFile(const char *concrete, const char *abstract, DFError **error);
-int DFCreateFile(const char *concrete, const char *abstract, DFError **error);
-
 // Abstraction level 2
 
 typedef struct DFConcreteDocument DFConcreteDocument;
@@ -43,4 +37,10 @@ int DFGet(DFConcreteDocument *concrete, DFAbstractDocument *abstract, DFError
**
 int DFPut(DFConcreteDocument *concrete, DFAbstractDocument *abstract, DFError **error);
 int DFCreate(DFConcreteDocument *concrete, DFAbstractDocument *abstract, DFError **error);
 
+// Abstraction level 1
+
+int DFGetFile(const char *concrete, const char *abstract, DFError **error);
+int DFPutFile(const char *concrete, const char *abstract, DFError **error);
+int DFCreateFile(const char *concrete, const char *abstract, DFError **error);
+
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/ef86c301/DocFormats/api/src/Operations.c
----------------------------------------------------------------------
diff --git a/DocFormats/api/src/Operations.c b/DocFormats/api/src/Operations.c
index f604e62..3b55180 100644
--- a/DocFormats/api/src/Operations.c
+++ b/DocFormats/api/src/Operations.c
@@ -16,7 +16,7 @@
 #include "DFFilesystem.h"
 #include "DFString.h"
 #include "DFPackage.h"
-#include "WordPackage.h"
+#include "Word.h"
 #include "DFHTML.h"
 #include "DFDOM.h"
 #include "DFXML.h"
@@ -31,178 +31,9 @@ struct DFConcreteDocument {
 struct DFAbstractDocument {
     size_t retainCount;
     DFPackage *package;
+    DFDocument *htmlDoc;
 };
 
-static int generateHTML(const char *packageFilename, const char *htmlFilename, DFError **error)
-{
-    int ok = 0;
-    DFPackage *rawPackage = NULL;
-    WordPackage *wordPackage = NULL;
-    char *htmlPath = DFPathDirName(htmlFilename);
-    DFBuffer *warnings = DFBufferNew();
-    DFDocument *htmlDoc = NULL;
-
-    rawPackage = DFPackageOpenZip(packageFilename,error);
-    if (rawPackage == NULL) {
-        DFErrorFormat(error,"%s: %s",packageFilename,DFErrorMessage(error));
-        goto end;
-    }
-
-    wordPackage = WordPackageOpenFrom(rawPackage,error);
-    if (wordPackage == NULL) {
-        DFErrorFormat(error,"%s: %s",packageFilename,DFErrorMessage(error));
-        goto end;
-    }
-
-    DFPackage *abstractPackage = DFPackageNewFilesystem(htmlPath,DFFileFormatHTML);
-    htmlDoc = WordPackageGenerateHTML(wordPackage,abstractPackage,"word",error,warnings);
-    DFPackageRelease(abstractPackage);
-    if (htmlDoc == NULL)
-        goto end;
-
-    if (warnings->len > 0) {
-        DFErrorFormat(error,"%s",warnings->data);
-        goto end;
-    }
-
-    HTML_safeIndent(htmlDoc->docNode,0);
-
-    if (!DFSerializeXMLFile(htmlDoc,0,0,htmlFilename,error)) {
-        DFErrorFormat(error,"%s: %s",htmlFilename,DFErrorMessage(error));
-        goto end;
-    }
-
-    ok = 1;
-
-end:
-    free(htmlPath);
-    DFBufferRelease(warnings);
-    DFDocumentRelease(htmlDoc);
-    DFPackageRelease(rawPackage);
-    WordPackageRelease(wordPackage);
-    return ok;
-}
-
-static int updateFrom(const char *packageFilename, const char *htmlFilename, DFError **error)
-{
-    int ok = 0;
-    DFPackage *rawPackage = NULL;
-    WordPackage *wordPackage = NULL;
-    DFDocument *htmlDoc = NULL;
-    DFBuffer *warnings = DFBufferNew();
-    char *htmlPath = DFPathDirName(htmlFilename);
-    DFPackage *abstractPackage = DFPackageNewFilesystem(htmlPath,DFFileFormatHTML);
-
-    htmlDoc = DFParseHTMLFile(htmlFilename,0,error);
-    if (htmlDoc == NULL) {
-        DFErrorFormat(error,"%s: %s",htmlFilename,DFErrorMessage(error));
-        goto end;
-    }
-
-    const char *idPrefix = "word";
-
-    if (!DFFileExists(packageFilename)) {
-
-        rawPackage = DFPackageCreateZip(packageFilename,error);
-        if (rawPackage == NULL) {
-            DFErrorFormat(error,"%s: %s",packageFilename,DFErrorMessage(error));
-            goto end;
-        }
-
-        wordPackage = WordPackageOpenNew(rawPackage,error);
-        if (wordPackage == NULL)
-            goto end;
-
-        // Change any id attributes starting with "word" or "odf" to a different prefix,
so they
-        // are not treated as references to nodes in the destination document. This is necessary
-        // if the HTML file was previously generated from a word or odf file, and we are
creating
-        // a new word or odf file from it.
-        HTMLBreakBDTRefs(htmlDoc->docNode,idPrefix);
-    }
-    else {
-        rawPackage = DFPackageOpenZip(packageFilename,error);
-        if (rawPackage == NULL) {
-            DFErrorFormat(error,"%s: %s",packageFilename,DFErrorMessage(error));
-            goto end;
-        }
-        wordPackage = WordPackageOpenFrom(rawPackage,error);
-        if (wordPackage == NULL)
-            goto end;
-    }
-
-    if (!WordPackageUpdateFromHTML(wordPackage,htmlDoc,abstractPackage,idPrefix,error,warnings))
-        goto end;
-
-    if (warnings->len > 0) {
-        DFErrorFormat(error,"%s",warnings->data);
-        goto end;
-    }
-
-    if (!WordPackageSave(wordPackage,error))
-        goto end;
-
-    ok = 1;
-
-end:
-    DFPackageRelease(rawPackage);
-    WordPackageRelease(wordPackage);
-    DFDocumentRelease(htmlDoc);
-    DFBufferRelease(warnings);
-    free(htmlPath);
-    DFPackageRelease(abstractPackage);
-    return ok;
-}
-
-int DFGetFile(const char *concrete, const char *abstract, DFError **error)
-{
-    int r = 0;
-    char *conExt = DFPathExtension(concrete);
-    char *absExt = DFPathExtension(abstract);
-
-    if (DFStringEqualsCI(conExt,"docx") && DFStringEqualsCI(absExt,"html")) {
-        r = generateHTML(concrete,abstract,error);
-    }
-
-//end:
-    free(conExt);
-    free(absExt);
-    return r;
-}
-
-int DFPutFile(const char *concrete, const char *abstract, DFError **error)
-{
-    int r = 0;
-    char *conExt = DFPathExtension(concrete);
-    char *absExt = DFPathExtension(abstract);
-
-    if (DFStringEqualsCI(conExt,"docx") && DFStringEqualsCI(absExt,"html")) {
-        r = updateFrom(concrete,abstract,error);
-    }
-
-//end:
-    free(conExt);
-    free(absExt);
-    return r;
-}
-
-int DFCreateFile(const char *concrete, const char *abstract, DFError **error)
-{
-    int r = 0;
-    char *conExt = DFPathExtension(concrete);
-    char *absExt = DFPathExtension(abstract);
-
-    if (DFStringEqualsCI(conExt,"docx") && DFStringEqualsCI(absExt,"html")) {
-        if (DFFileExists(concrete) && !DFDeleteFile(concrete,error))
-            goto end;
-        r = updateFrom(concrete,abstract,error);
-    }
-
-end:
-    free(conExt);
-    free(absExt);
-    return r;
-}
-
 DFConcreteDocument *DFConcreteDocumentNew(DFPackage *package)
 {
     DFConcreteDocument *concrete = (DFConcreteDocument *)calloc(1,sizeof(DFConcreteDocument));
@@ -294,23 +125,180 @@ void DFAbstractDocumentRelease(DFAbstractDocument *abstract)
         return;
 
     DFPackageRelease(abstract->package);
+    DFDocumentRelease(abstract->htmlDoc);
     free(abstract);
 }
 
 int DFGet(DFConcreteDocument *concrete, DFAbstractDocument *abstract, DFError **error)
 {
-    DFErrorFormat(error,"DFGet not yet implemented");
-    return 0;
+    if (DFPackageFormat(abstract->package) != DFFileFormatHTML) {
+        DFErrorFormat(error,"Abstract document must be in HTML format");
+        return 0;
+    }
+
+    DFDocument *htmlDoc = NULL;
+    switch (DFPackageFormat(concrete->package)) {
+        case DFFileFormatDocx:
+            htmlDoc = WordGet(concrete->package,abstract->package,error);
+            break;
+        default:
+            DFErrorFormat(error,"Unsupported file format");
+            break;
+    }
+
+    if (htmlDoc == NULL)
+        return 0;
+
+    DFDocumentRelease(abstract->htmlDoc);
+    abstract->htmlDoc = htmlDoc;
+    return 1;
+}
+
+int DFPut(DFConcreteDocument *concreteDoc, DFAbstractDocument *abstractDoc, DFError **error)
+{
+    if (DFPackageFormat(abstractDoc->package) != DFFileFormatHTML) {
+        DFErrorFormat(error,"Abstract document must be in HTML format");
+        return 0;
+    }
+
+    int ok = 0;
+    switch (DFPackageFormat(concreteDoc->package)) {
+        case DFFileFormatDocx:
+            ok = WordPut(concreteDoc->package,abstractDoc->package,abstractDoc->htmlDoc,error);
+            break;
+        default:
+            DFErrorFormat(error,"Unsupported file format");
+            break;
+    }
+    return ok;
+}
+
+int DFCreate(DFConcreteDocument *concreteDoc, DFAbstractDocument *abstractDoc, DFError **error)
+{
+    if (DFPackageFormat(abstractDoc->package) != DFFileFormatHTML) {
+        DFErrorFormat(error,"Abstract document must be in HTML format");
+        return 0;
+    }
+
+    int ok = 0;
+    switch (DFPackageFormat(concreteDoc->package)) {
+        case DFFileFormatDocx:
+            ok = WordCreate(concreteDoc->package,abstractDoc->package,abstractDoc->htmlDoc,error);
+            break;
+        default:
+            DFErrorFormat(error,"Unsupported file format");
+            break;
+    }
+    return ok;
+}
+
+int DFGetFile(const char *concreteFilename, const char *abstractFilename, DFError **error)
+{
+    int r = 0;
+    char *abstractPath = DFPathDirName(abstractFilename);
+    DFPackage *abstractPackage = DFPackageNewFilesystem(abstractPath,DFFileFormatHTML);
+    DFConcreteDocument *concreteDoc = NULL;
+    DFAbstractDocument *abstractDoc = NULL;
+
+    concreteDoc = DFConcreteDocumentOpenFile(concreteFilename,error);
+    if (concreteDoc == NULL) {
+        DFErrorFormat(error,"%s: %s",concreteFilename,DFErrorMessage(error));
+        goto end;
+    }
+
+    abstractDoc = DFAbstractDocumentNew(abstractPackage);
+
+    if (!DFGet(concreteDoc,abstractDoc,error) || (abstractDoc->htmlDoc == NULL)) {
+        DFErrorFormat(error,"%s: %s",concreteFilename,DFErrorMessage(error));
+        goto end;
+    }
+
+    if (DFFileExists(abstractFilename)) {
+        DFErrorFormat(error,"%s: File already exists",abstractFilename);
+        goto end;
+    }
+
+    if (!DFSerializeXMLFile(abstractDoc->htmlDoc,0,0,abstractFilename,error)) {
+        DFErrorFormat(error,"%s: %s",abstractFilename,DFErrorMessage(error));
+        goto end;
+    }
+
+    r = 1;
+
+end:
+    free(abstractPath);
+    DFPackageRelease(abstractPackage);
+    DFConcreteDocumentRelease(concreteDoc);
+    DFAbstractDocumentRelease(abstractDoc);
+    return r;
 }
 
-int DFPut(DFConcreteDocument *concrete, DFAbstractDocument *abstract, DFError **error)
+int DFPutFile(const char *concreteFilename, const char *abstractFilename, DFError **error)
 {
-    DFErrorFormat(error,"DFPut not yet implemented");
-    return 0;
+    int ok = 0;
+    DFDocument *htmlDoc2 = NULL;
+    char *abstractPath = DFPathDirName(abstractFilename);
+    DFPackage *abstractPackage2 = DFPackageNewFilesystem(abstractPath,DFFileFormatHTML);
+    DFConcreteDocument *concreteDoc = NULL;
+    DFAbstractDocument *abstractDoc = NULL;
+
+    htmlDoc2 = DFParseHTMLFile(abstractFilename,0,error);
+    if (htmlDoc2 == NULL) {
+        DFErrorFormat(error,"%s: %s",abstractFilename,DFErrorMessage(error));
+        goto end;
+    }
+
+    concreteDoc = DFConcreteDocumentOpenFile(concreteFilename,error);
+    if (concreteDoc == NULL) {
+        DFErrorFormat(error,"%s: %s",concreteFilename,DFErrorMessage(error));
+        goto end;
+    }
+
+    abstractDoc = DFAbstractDocumentNew(abstractPackage2);
+    abstractDoc->htmlDoc = DFDocumentRetain(htmlDoc2);
+
+    ok = DFPut(concreteDoc,abstractDoc,error);
+
+end:
+    DFDocumentRelease(htmlDoc2);
+    free(abstractPath);
+    DFPackageRelease(abstractPackage2);
+    DFConcreteDocumentRelease(concreteDoc);
+    DFAbstractDocumentRelease(abstractDoc);
+    return ok;
 }
 
-int DFCreate(DFConcreteDocument *concrete, DFAbstractDocument *abstract, DFError **error)
+int DFCreateFile(const char *concreteFilename, const char *abstractFilename, DFError **error)
 {
-    DFErrorFormat(error,"DFCreate not yet implemented");
-    return 0;
+    int ok = 0;
+    DFDocument *htmlDoc = NULL;
+    char *abstractPath = DFPathDirName(abstractFilename);
+    DFPackage *abstractPackage = DFPackageNewFilesystem(abstractPath,DFFileFormatHTML);
+    DFConcreteDocument *concreteDoc = NULL;
+    DFAbstractDocument *abstractDoc = NULL;
+
+    htmlDoc = DFParseHTMLFile(abstractFilename,0,error);
+    if (htmlDoc == NULL) {
+        DFErrorFormat(error,"%s: %s",abstractFilename,DFErrorMessage(error));
+        goto end;
+    }
+
+    concreteDoc = DFConcreteDocumentCreateFile(concreteFilename,error);
+    if (concreteDoc == NULL) {
+        DFErrorFormat(error,"%s: %s",concreteFilename,DFErrorMessage(error));
+        goto end;
+    }
+
+    abstractDoc = DFAbstractDocumentNew(abstractPackage);
+    abstractDoc->htmlDoc = DFDocumentRetain(htmlDoc);
+
+    ok = DFCreate(concreteDoc,abstractDoc,error);
+
+end:
+    DFDocumentRelease(htmlDoc);
+    free(abstractPath);
+    DFPackageRelease(abstractPackage);
+    DFConcreteDocumentRelease(concreteDoc);
+    DFAbstractDocumentRelease(abstractDoc);
+    return ok;
 }

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/ef86c301/DocFormats/filters/ooxml/src/word/Word.c
----------------------------------------------------------------------
diff --git a/DocFormats/filters/ooxml/src/word/Word.c b/DocFormats/filters/ooxml/src/word/Word.c
index 6d1a367..357b8d8 100644
--- a/DocFormats/filters/ooxml/src/word/Word.c
+++ b/DocFormats/filters/ooxml/src/word/Word.c
@@ -76,3 +76,107 @@ end:
     DFPackageRelease(abstractPackage);
     return ok;
 }
+
+DFDocument *WordGet(DFPackage *concretePackage, DFPackage *abstractPackage, DFError **error)
+{
+    int ok = 0;
+    WordPackage *wordPackage = NULL;
+    DFBuffer *warnings = DFBufferNew();
+    DFDocument *htmlDoc = NULL;
+
+    wordPackage = WordPackageOpenFrom(concretePackage,error);
+    if (wordPackage == NULL)
+        goto end;
+
+    htmlDoc = WordPackageGenerateHTML(wordPackage,abstractPackage,"word",error,warnings);
+    if (htmlDoc == NULL)
+        goto end;
+
+    if (warnings->len > 0) {
+        DFErrorFormat(error,"%s",warnings->data);
+        goto end;
+    }
+
+    HTML_safeIndent(htmlDoc->docNode,0);
+
+    ok = 1;
+
+end:
+    DFBufferRelease(warnings);
+    WordPackageRelease(wordPackage);
+    if (ok) {
+        return htmlDoc;
+    }
+    else {
+        DFDocumentRelease(htmlDoc);
+        return NULL;
+    }
+}
+
+int WordPut(DFPackage *concretePackage, DFPackage *abstractPackage, DFDocument *htmlDoc,
DFError **error)
+{
+    int ok = 0;
+    WordPackage *wordPackage = NULL;
+    DFBuffer *warnings = DFBufferNew();
+
+    const char *idPrefix = "word";
+
+    wordPackage = WordPackageOpenFrom(concretePackage,error);
+    if (wordPackage == NULL)
+        goto end;
+
+    if (!WordPackageUpdateFromHTML(wordPackage,htmlDoc,abstractPackage,idPrefix,error,warnings))
+        goto end;
+
+    if (warnings->len > 0) {
+        DFErrorFormat(error,"%s",warnings->data);
+        goto end;
+    }
+
+    if (!WordPackageSave(wordPackage,error))
+        goto end;
+
+    ok = 1;
+
+end:
+    WordPackageRelease(wordPackage);
+    DFBufferRelease(warnings);
+    return ok;
+}
+
+int WordCreate(DFPackage *concretePackage, DFPackage *abstractPackage, DFDocument *htmlDoc,
DFError **error)
+{
+    int ok = 0;
+    WordPackage *wordPackage = NULL;
+    DFBuffer *warnings = DFBufferNew();
+
+    const char *idPrefix = "word";
+
+    wordPackage = WordPackageOpenNew(concretePackage,error);
+    if (wordPackage == NULL)
+        goto end;
+
+    // Change any id attributes starting with "word" or "odf" to a different prefix, so they
+    // are not treated as references to nodes in the destination document. This is necessary
+    // if the HTML file was previously generated from a word or odf file, and we are creating
+    // a new word or odf file from it.
+    HTMLBreakBDTRefs(htmlDoc->docNode,idPrefix);
+
+    if (!WordPackageUpdateFromHTML(wordPackage,htmlDoc,abstractPackage,idPrefix,error,warnings))
+        goto end;
+
+    if (warnings->len > 0) {
+        DFErrorFormat(error,"%s",warnings->data);
+        goto end;
+    }
+
+    if (!WordPackageSave(wordPackage,error))
+        goto end;
+
+    ok = 1;
+
+end:
+    WordPackageRelease(wordPackage);
+    DFBufferRelease(warnings);
+    return ok;
+}

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/ef86c301/DocFormats/filters/ooxml/src/word/Word.h
----------------------------------------------------------------------
diff --git a/DocFormats/filters/ooxml/src/word/Word.h b/DocFormats/filters/ooxml/src/word/Word.h
index ab7d854..2b8ac1b 100644
--- a/DocFormats/filters/ooxml/src/word/Word.h
+++ b/DocFormats/filters/ooxml/src/word/Word.h
@@ -16,6 +16,7 @@
 #define DocFormats_Word_h
 
 #include "DFError.h"
+#include "DFPackage.h"
 #include "CSSStyle.h"
 #include "CSSSheet.h"
 
@@ -28,4 +29,8 @@ CSSStyle *WordSetupTableGridStyle(CSSSheet *styleSheet, int *changed);
 
 int DFHTMLToWord(const char *sourcePath, const char *destPath, DFError **error);
 
+DFDocument *WordGet(DFPackage *concretePackage, DFPackage *abstractPackage, DFError **error);
+int WordPut(DFPackage *concretePackage, DFPackage *abstractPackage, DFDocument *htmlDoc,
DFError **error);
+int WordCreate(DFPackage *concretePackage, DFPackage *abstractPackage, DFDocument *htmlDoc,
DFError **error);
+
 #endif


Mime
View raw message