Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add immutable document to store #3506

Merged
merged 1 commit into from Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/main/java/org/dita/dost/module/ChunkModule.java
Expand Up @@ -8,6 +8,7 @@
*/
package org.dita.dost.module;

import net.sf.saxon.s9api.XdmNode;
import org.dita.dost.exception.DITAOTException;
import org.dita.dost.pipeline.AbstractPipelineInput;
import org.dita.dost.pipeline.AbstractPipelineOutput;
Expand All @@ -17,15 +18,15 @@
import org.dita.dost.util.Job;
import org.dita.dost.util.Job.FileInfo;
import org.dita.dost.writer.TopicRefWriter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import static net.sf.saxon.s9api.streams.Steps.attribute;
import static net.sf.saxon.s9api.streams.Steps.child;
import static org.apache.commons.io.FileUtils.deleteQuietly;
import static org.apache.commons.io.FileUtils.moveFile;
import static org.dita.dost.util.Constants.*;
Expand Down Expand Up @@ -119,14 +120,15 @@ private boolean hasChanges(final Map<URI, URI> changeTable) {
* @throws DITAOTException if reading ditamap fails
*/
private boolean isEclipseMap(final URI mapFile) throws DITAOTException {
Document doc;
XdmNode doc;
try {
doc = job.getStore().getDocument(mapFile);
doc = job.getStore().getImmutableNode(mapFile);
} catch (final IOException e) {
throw new DITAOTException("Failed to parse input map: " + e.getMessage(), e);
}
final Element root = doc.getDocumentElement();
return ECLIPSEMAP_PLUGIN.matches(root);
return doc
.select(child().first().then(attribute(ATTRIBUTE_NAME_CLASS)))
.anyMatch(xdmItems -> ECLIPSEMAP_PLUGIN.matches(xdmItems.getStringValue()));
}

/**
Expand Down
Expand Up @@ -347,7 +347,7 @@ private void outputSubjectScheme() throws DITAOTException {
}
if (children != null) {
for (final URI childpath: children) {
final Document childRoot = job.getStore().getDocument(job.getInputFile().resolve(childpath.getPath()));
final Document childRoot = job.getStore().getImmutableDocument(job.getInputFile().resolve(childpath.getPath()));
mergeScheme(parentRoot, childRoot);
generateScheme(new File(job.tempDir, childpath.getPath() + SUBJECT_SCHEME_EXTENSION), childRoot);
}
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/org/dita/dost/store/Store.java
Expand Up @@ -10,6 +10,7 @@

import net.sf.saxon.s9api.Destination;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XdmNode;
import org.dita.dost.exception.DITAOTException;
import org.w3c.dom.Document;
import org.xml.sax.ContentHandler;
Expand Down Expand Up @@ -60,6 +61,25 @@ public interface Store {
*/
Source getSource(URI path);

/**
* Get immutable DOM document for file. If mutating methods are called,
* {@link UnsupportedOperationException} is thrown.
*
* @param path temporary file URI, absolute or relative
* @return document or null if not available
* @throws java.io.FileNotFoundException if file does not exist or cannot be read
*/
Document getImmutableDocument(URI path) throws IOException;

/**
* Get immutable XsdNode for file.
*
* @param path temporary file URI, absolute or relative
* @return document or null if not available
* @throws java.io.FileNotFoundException if file does not exist or cannot be read
*/
XdmNode getImmutableNode(final URI path) throws IOException;

/**
* Get DOM document for file.
*
Expand All @@ -78,6 +98,15 @@ public interface Store {
*/
void writeDocument(Document doc, URI dst) throws IOException;

/**
* Write XdmNode to file.
*
* @param node XdmNode to store
* @param dst destination file URI, absolute or relative
* @throws IOException if serializing file fails
*/
void writeDocument(XdmNode node, URI dst) throws IOException;

/**
* Get temporary file destination
*
Expand Down
24 changes: 22 additions & 2 deletions src/main/java/org/dita/dost/store/StreamStore.java
Expand Up @@ -46,6 +46,21 @@ public StreamStore(XMLUtils xmlUtils) {
this.xmlUtils = xmlUtils;
}

@Override
public Document getImmutableDocument(final URI path) throws IOException {
// return (Document) NodeOverNodeInfo.wrap(getImmutableNode(path).getUnderlyingNode());
return getDocument(path);
}

@Override
public XdmNode getImmutableNode(final URI path) throws IOException {
try {
return xmlUtils.getProcessor().newDocumentBuilder().build(new StreamSource(path.toString()));
} catch (SaxonApiException e) {
throw new IOException(e);
}
}

@Override
public Document getDocument(final URI path) throws IOException {
try {
Expand All @@ -57,10 +72,15 @@ public Document getDocument(final URI path) throws IOException {

@Override
public void writeDocument(final Document doc, final URI dst) throws IOException {
final XdmNode source = xmlUtils.getProcessor().newDocumentBuilder().wrap(doc);
writeDocument(source, dst);
}

@Override
public void writeDocument(final XdmNode node, final URI dst) throws IOException {
try {
final Serializer serializer = getSerializer(dst);
final XdmNode source = xmlUtils.getProcessor().newDocumentBuilder().wrap(doc);
serializer.serializeNode(source);
serializer.serializeNode(node);
} catch (SaxonApiException e) {
throw new IOException(e);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/dita/dost/util/DelayConrefUtils.java
Expand Up @@ -73,7 +73,7 @@ public boolean findTopicId(final File absolutePathToFile, final String id) {
}
try {
//load the file
final Document root = job.getStore().getDocument(absolutePathToFile.toURI());
final Document root = job.getStore().getImmutableDocument(absolutePathToFile.toURI());

//get root element
final Element doc = root.getDocumentElement();
Expand Down Expand Up @@ -122,7 +122,7 @@ public List<Boolean> checkExport(String href, final String id, final String key,
try {
//load export.xml only once
if (root == null) {
root = job.getStore().getDocument(exportFile.toURI());
root = job.getStore().getImmutableDocument(exportFile.toURI());
}
//get file node which contains the export node
final Element fileNode = searchForKey(root.getDocumentElement(), href, "file");
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/org/dita/dost/util/XMLUtils.java
Expand Up @@ -860,9 +860,19 @@ public void writeDocument(final Document doc, final File dst) throws IOException
* @throws IOException if serializing file fails
*/
public void writeDocument(final Node doc, final ContentHandler dst) throws IOException {
writeDocument(processor.newDocumentBuilder().wrap(doc), dst);
}

/**
* Write XdmNode to SAX pipe.
*
* @param source XdmNode to store
* @param dst SAX pipe
* @throws IOException if serializing file fails
*/
public void writeDocument(final XdmNode source, final ContentHandler dst) throws IOException {
try {
final SAXDestination destination = new SAXDestination(dst);
final XdmNode source = processor.newDocumentBuilder().wrap(doc);
processor.writeXdmValue(source, destination);
} catch (SaxonApiException e) {
throw new IOException(e);
Expand Down
18 changes: 11 additions & 7 deletions src/main/java/org/dita/dost/writer/include/IncludeXml.java
Expand Up @@ -8,17 +8,20 @@

package org.dita.dost.writer.include;

import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XdmItem;
import net.sf.saxon.s9api.XdmNode;
import org.dita.dost.log.DITAOTLogger;
import org.dita.dost.util.Job;
import org.dita.dost.util.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;

import java.io.IOException;
import java.net.URI;
import java.util.stream.Stream;

import static net.sf.saxon.s9api.streams.Steps.id;
import static org.dita.dost.util.Constants.ATTRIBUTE_NAME_HREF;
import static org.dita.dost.util.URLUtils.stripFragment;
import static org.dita.dost.util.URLUtils.toURI;
Expand All @@ -43,12 +46,13 @@ boolean include(final Attributes atts) {
final URI hrefValue = toURI(atts.getValue(ATTRIBUTE_NAME_HREF));
final Job.FileInfo fileInfo = job.getFileInfo(stripFragment(currentFile.resolve(hrefValue)));
try {
final Document doc = job.getStore().getDocument(fileInfo.src);
Node src = null;
final XdmNode doc = job.getStore().getImmutableNode(fileInfo.src);
final XdmNode src;
if (hrefValue.getFragment() != null) {
src = doc.getElementById(hrefValue.getFragment());
}
if (src == null) {
final XdmItem id = XdmAtomicValue.makeAtomicValue(hrefValue.getFragment());
final Stream<XdmNode> idStream = (Stream<XdmNode>) id(doc).apply(id);
src = idStream.findAny().orElse(doc);
} else {
src = doc;
}

Expand Down