Skip to content

Commit

Permalink
Next (yet unstable) release synchronization of added features
Browse files Browse the repository at this point in the history
(Insert-Document on placeholders, extended values...).
Currently unstable, but used and tested.
  • Loading branch information
Moritz Riebe committed May 11, 2016
1 parent 92dfe5f commit 88d8e77
Show file tree
Hide file tree
Showing 7 changed files with 1,197 additions and 99 deletions.
182 changes: 91 additions & 91 deletions nbproject/project.properties
Original file line number Diff line number Diff line change
@@ -1,91 +1,91 @@
auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
#Mon Nov 16 15:32:04 CET 2015
excludes=
file.reference.hamcrest-core-1.3.jar=third-party/hamcrest-core-1.3.jar
file.reference.javax.annotation_2.0.2_jsr305_impl.jar=third-party/javax.annotation_2.0.2_jsr305_impl.jar
file.reference.junit-4.12.jar=third-party/junit-4.12.jar
jar.archive.disabled=${jnlp.enabled}
jar.index=${jnlp.enabled}
javac.deprecation=true
build.test.results.dir=${build.dir}/test/results
javac.external.vm=false
jnlp.codebase.type=no.codebase
jnlp.descriptor=application
jnlp.enabled=false
jnlp.mixed.code=default
jnlp.offline-allowed=false
jnlp.signed=false
jnlp.signing=
jnlp.signing.alias=
jnlp.signing.keystore=
# Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found.
manifest.custom.application.library.allowable.codebase=
# Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts.
manifest.custom.caller.allowable.codebase=
# Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed
manifest.custom.codebase=
# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions)
manifest.custom.permissions=
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
javadoc.nonavbar=false
application.homepage=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
javac.processorpath=\
${javac.classpath}
javac.target=1.8
annotation.processing.processors.list=
javadoc.noindex=false
javadoc.additionalparam=-header "MZ Office Document API (Moritz Riebe und Andreas Zaschka GbR)"
includes=**
build.classes.dir=${build.dir}/classes
source.encoding=UTF-8
javadoc.author=true
test.src.dir=test
build.dir=build
build.test.classes.dir=${build.dir}/test/classes
platform.active=default_platform
javac.compilerargs=
dist.jar=${dist.dir}/com.mz.solutions.office_lib.jar
javac.test.processorpath=${javac.test.classpath}
javadoc.use=true
dist.archive.excludes=
build.sysclasspath=ignore
debug.test.classpath=${run.test.classpath}
dist.dir=dist
build.classes.excludes=**/*.java,**/*.form
javadoc.splitindex=true
javadoc.encoding=${source.encoding}
javac.source=1.8
application.vendor=Moritz Riebe und Andreas Zaschka GbR
junit.selected.version=4
debug.classpath=${run.classpath}
project.licensePath=license/LICENSE_HEADER_AGPL3.TXT
run.jvmargs=
build.generated.dir=${build.dir}/generated
jar.compress=false
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${file.reference.hamcrest-core-1.3.jar}:\
${file.reference.junit-4.12.jar}
javadoc.private=false
annotation.processing.run.all.processors=true
application.title=MZ Office Document API
meta.inf.dir=${src.dir}/META-INF
annotation.processing.enabled=true
dist.javadoc.dir=${dist.dir}/javadoc
src.dir=src
mkdist.disabled=true
endorsed.classpath=
javac.classpath=\
${file.reference.javax.annotation_2.0.2_jsr305_impl.jar}
annotation.processing.enabled.in.editor=false
build.generated.sources.dir=${build.dir}/generated-sources
javadoc.version=true
javadoc.windowtitle=MZ Office Document API (Moritz Riebe und Andreas Zaschka GbR)
javadoc.notree=false
auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
#Mon Nov 16 15:32:04 CET 2015
excludes=
file.reference.hamcrest-core-1.3.jar=third-party/hamcrest-core-1.3.jar
file.reference.javax.annotation_2.0.2_jsr305_impl.jar=third-party/javax.annotation_2.0.2_jsr305_impl.jar
file.reference.junit-4.12.jar=third-party/junit-4.12.jar
jar.archive.disabled=${jnlp.enabled}
jar.index=${jnlp.enabled}
javac.deprecation=true
build.test.results.dir=${build.dir}/test/results
javac.external.vm=false
jnlp.codebase.type=no.codebase
jnlp.descriptor=application
jnlp.enabled=false
jnlp.mixed.code=default
jnlp.offline-allowed=false
jnlp.signed=false
jnlp.signing=
jnlp.signing.alias=
jnlp.signing.keystore=
# Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found.
manifest.custom.application.library.allowable.codebase=
# Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts.
manifest.custom.caller.allowable.codebase=
# Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed
manifest.custom.codebase=
# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions)
manifest.custom.permissions=
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
javadoc.nonavbar=false
application.homepage=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
javac.processorpath=\
${javac.classpath}
javac.target=1.8
annotation.processing.processors.list=
javadoc.noindex=false
javadoc.additionalparam=-header "MZ Office Document API (Moritz Riebe und Andreas Zaschka GbR)"
includes=**
build.classes.dir=${build.dir}/classes
source.encoding=UTF-8
javadoc.author=true
test.src.dir=test
build.dir=build
build.test.classes.dir=${build.dir}/test/classes
platform.active=default_platform
javac.compilerargs=-Xlint:unchecked
dist.jar=${dist.dir}/com.mz.solutions.office_lib.jar
javac.test.processorpath=${javac.test.classpath}
javadoc.use=true
dist.archive.excludes=
build.sysclasspath=ignore
debug.test.classpath=${run.test.classpath}
dist.dir=dist
build.classes.excludes=**/*.java,**/*.form
javadoc.splitindex=true
javadoc.encoding=${source.encoding}
javac.source=1.8
application.vendor=Moritz Riebe und Andreas Zaschka GbR
junit.selected.version=4
debug.classpath=${run.classpath}
project.licensePath=license/LICENSE_HEADER_AGPL3.TXT
run.jvmargs=
build.generated.dir=${build.dir}/generated
jar.compress=false
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${file.reference.hamcrest-core-1.3.jar}:\
${file.reference.junit-4.12.jar}
javadoc.private=false
annotation.processing.run.all.processors=true
application.title=MZ Office Document API
meta.inf.dir=${src.dir}/META-INF
annotation.processing.enabled=true
dist.javadoc.dir=${dist.dir}/javadoc
src.dir=src
mkdist.disabled=true
endorsed.classpath=
javac.classpath=\
${file.reference.javax.annotation_2.0.2_jsr305_impl.jar}
annotation.processing.enabled.in.editor=false
build.generated.sources.dir=${build.dir}/generated-sources
javadoc.version=true
javadoc.windowtitle=MZ Office Document API (Moritz Riebe und Andreas Zaschka GbR)
javadoc.notree=false
136 changes: 128 additions & 8 deletions src/com/mz/solutions/office/MicrosoftDocument.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@

import com.mz.solutions.office.OfficeDocumentException.DocumentPlaceholderMissingException;
import com.mz.solutions.office.OfficeDocumentException.NoDataForDocumentGenerationException;
import com.mz.solutions.office.extension.ExtendedValue;
import com.mz.solutions.office.extension.Extension;
import com.mz.solutions.office.extension.MicrosoftCustomXml;
import com.mz.solutions.office.extension.MicrosoftInsertDoc;
import com.mz.solutions.office.model.DataMap;
import com.mz.solutions.office.model.DataPage;
import com.mz.solutions.office.model.DataTable;
Expand Down Expand Up @@ -61,16 +63,28 @@ final class MicrosoftDocument extends AbstractOfficeXmlDocument {

private static final String ZIP_DOC_DOCUMENT = "word/document.xml";
private static final String ZIP_DOC_STYLES = "word/styles.xml";
private static final String ZIP_REL_RELS = "word/_rels/document.xml.rels";

private static final String ZIP_CONTENT_TYPES = "[Content_Types].xml";

/**
* Speichert die Referenz wenn die Custom XML Erweiterung verwendet wurde;
* wurde die Erweiterung nicht verwendet, bleibt das Feld mit null belegt.
*/
@Nullable
private MicrosoftCustomXml extCustomXml;

/** Speichert die Referenz zur altChunk-Erweiterung, sobald diese verwendet wurde. */
private InnerAltChunkExtension extAltChunk = new InnerAltChunkExtension();

private final Document sourceRelationships;
private final Document sourceContentTypes;

public MicrosoftDocument(OfficeDocumentFactory factory, Path document) {
super(factory, document, ZIP_DOC_DOCUMENT, ZIP_DOC_STYLES);

this.sourceRelationships = loadFileAsXml(ZIP_REL_RELS);
this.sourceContentTypes = loadFileAsXml(ZIP_CONTENT_TYPES);
}

@Override
Expand All @@ -93,6 +107,10 @@ public <T extends Extension> Optional<T> extension(Class<T> extType) {
return Optional.of((T) extCustomXml);
}

if (extType == MicrosoftInsertDoc.class) {
return Optional.of((T) extAltChunk);
}

return Optional.empty();
}

Expand Down Expand Up @@ -127,6 +145,14 @@ private void fillDocuments(
final Document newContent = (Document) sourceContent.cloneNode(true);
final Document newStyles = (Document) sourceStyles.cloneNode(true);

final Document newRelationships = (Document) sourceRelationships.cloneNode(true);
final Document newContentTypes = (Document) sourceContentTypes.cloneNode(true);

extAltChunk.setCurrentZipFile(outputDocument)
.setRelationshipDocument(newRelationships)
.setWordDocument(newContent)
.setContentTypesDocument(newContentTypes);

normalizeInstrTextFields(newContent);

final Node wordBody = findDocumentBody(newContent);
Expand All @@ -143,14 +169,8 @@ private void fillDocuments(
final DataPage pageData = dataPages.next();
final Node newPageBody = wordBody.cloneNode(true);

replaceAllFields(newPageBody, pageData);

while (newPageBody.hasChildNodes()) {
newWordBody.appendChild(
newPageBody.removeChild(newPageBody.getFirstChild())
);
}

// Zeilenumbruch nur Einfügen, wenn es sich NICHT um die
// Seite handelt
if (firstPage == false && needToInsertPageBreak()) {
final Node wordBreak = newContent.createElement("w:br");
final NamedNodeMap attributes = wordBreak.getAttributes();
Expand All @@ -163,6 +183,17 @@ private void fillDocuments(
newWordBody.appendChild(wordBreak);
}

// Ersetzen und alle Nodes in dem fortlaufenden neuen Word-Inhalt
// übernehmen. #removeChild(..) gibt den entfernten Node zurück.

replaceAllFields(newPageBody, pageData);

while (newPageBody.hasChildNodes()) {
newWordBody.appendChild(
newPageBody.removeChild(newPageBody.getFirstChild())
);
}

missingData = false;
firstPage = false;
}
Expand All @@ -186,6 +217,9 @@ private void fillDocuments(
overwrite(outputDocument, ZIP_DOC_DOCUMENT, newContent);
overwrite(outputDocument, ZIP_DOC_STYLES, newStyles);

overwrite(outputDocument, ZIP_REL_RELS, newRelationships);
overwrite(outputDocument, ZIP_CONTENT_TYPES, newContentTypes);

//// EXTENSIONS DURCHLAUFEN LASSEN

if (null != extCustomXml) {
Expand Down Expand Up @@ -419,6 +453,19 @@ private void replaceField(Node instrTextNode, DataValueMap values) {
return; // Joar anderweitiger Feldbefehl
}

// Sonderfall: Ist der zurückgegebene DataValue ein erweiterter Wert, dann muss mindestens
// geprüft werden ob diese Art und bekannt ist.
final DataValue dataValue = value.get();
if (dataValue.isExtendedValue()) {
final ExtendedValue extValue = dataValue.extendedValue();

if (extAltChunk.isAltChunkExtValue(extValue)) {
// Platzhalter durch w:altChunk ersetzen
subReplaceFieldWithAltChunk(instrTextNode, extValue);
return;
}
}

// w:instrText ersetzen durch w:t oder längerer Formatierungskette
final Node wordRun = instrTextNode.getParentNode();
final List<Node> formattedNodes = createFormattedNodes(
Expand Down Expand Up @@ -530,6 +577,18 @@ private List<Node> createFormattedNodes(
return formattedNodes;
}

private void subReplaceFieldWithAltChunk(Node instrTextNode, ExtendedValue extValue) {
// - instrTextNode -> Platzhalter vollständig (samt ABSATZ!) entfernen
// - Weitere Behandlung an die Erweiterungsimplementierung geben
final Node fieldParent = instrTextNode.getParentNode();
final Node contentParent = fieldParent.getParentNode();

extAltChunk.insertAltChunkAt(instrTextNode, extValue);

// Jetzt erst entfernen
//contentParent.removeChild(fieldParent);
}

private Node createWordTextNode(Document document, String textContent) {
final Node wordText = document.createElement("w:t");
final Node textNode = document.createTextNode(textContent);
Expand Down Expand Up @@ -795,5 +854,66 @@ public String toString() {
}

}

////////////////////////////////////////////////////////////////////////////////////////////////
// IMPLEMENTIERUNG DER MS ERWEITERUNG FÜR ALTERNATIVE CHUNK ELEMENTE/PLATZHALTER
////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Unterklasse der Erweiterung um w:altChunk mit der Implementierung für ZIP Container.
*/
private class InnerAltChunkExtension extends MicrosoftInsertDoc {

private ZIPDocumentFile zipFile;
private Document wordDocument;
private Document relationshipDocument;
private Document contentTypesDocument;

public InnerAltChunkExtension setCurrentZipFile(ZIPDocumentFile zipFile) {
this.zipFile = zipFile;
return this;
}

public InnerAltChunkExtension setWordDocument(Document doc) {
this.wordDocument = doc;
return this;
}

public InnerAltChunkExtension setRelationshipDocument(Document doc) {
this.relationshipDocument = doc;
return this;
}

@Override
protected Document getWordDocument() {
return wordDocument;
}

@Override
protected Document getRelationshipDocument() {
return relationshipDocument;
}

@Override
protected Document getContentTypeDocument() {
return this.contentTypesDocument;
}

@Override
protected void overwritePartInContainer(String partName, byte[] data) {
assert null != partName : "partName == null";
assert null != data : "data == null";
assert null != zipFile : "#setCurrentZipFile(null??)";

zipFile.createNewFileInZip(partName);
zipFile.overwrite(partName, data);
}

private InnerAltChunkExtension setContentTypesDocument(Document newContentTypes) {
this.contentTypesDocument = newContentTypes;
return this;
}

}

}
Loading

0 comments on commit 88d8e77

Please sign in to comment.