Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,20 @@
package schemacrawler.tools.command.text.embeddeddiagram;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.deleteIfExists;
import static java.nio.file.Files.newBufferedReader;
import static java.nio.file.Files.newBufferedWriter;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.nio.file.StandardOpenOption.WRITE;
import static java.util.Objects.requireNonNull;
import static schemacrawler.tools.command.text.diagram.options.DiagramOutputFormat.htmlx;
import static schemacrawler.tools.command.text.diagram.options.DiagramOutputFormat.svg;
import static schemacrawler.tools.command.text.schema.options.TextOutputFormat.html;
import static us.fatehi.utility.IOUtility.copy;
import static us.fatehi.utility.IOUtility.createTempFilePath;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import schemacrawler.schemacrawler.exceptions.ExecutionRuntimeException;
import schemacrawler.schemacrawler.exceptions.SchemaCrawlerException;
Expand All @@ -43,31 +39,9 @@

public class EmbeddedDiagramRenderer extends AbstractSchemaCrawlerCommand<DiagramOptions> {

private static final Logger LOGGER = Logger.getLogger(EmbeddedDiagramRenderer.class.getName());

private static final Pattern svgInsertionPoint = Pattern.compile("<h2.*Tables.*h2>");
private static final Pattern svgStart = Pattern.compile("<svg.*");

private static void insertSvg(
final BufferedWriter finalHtmlFileWriter, final BufferedReader baseSvgFileReader)
throws IOException {
finalHtmlFileWriter.append(System.lineSeparator());
boolean skipLines = true;
boolean isSvgStart = false;
String line;
while ((line = baseSvgFileReader.readLine()) != null) {
if (skipLines) {
isSvgStart = svgStart.matcher(line).matches();
skipLines = !isSvgStart;
}
if (!skipLines) {
if (isSvgStart) {
line = "<svg";
isSvgStart = false;
}
finalHtmlFileWriter.append(line).append(System.lineSeparator());
}
}
finalHtmlFileWriter.append(System.lineSeparator());
}

private final GraphExecutorFactory graphExecutorFactory;

Expand All @@ -83,31 +57,40 @@ public void execute() {
checkCatalog();

try {
final String stem = "schemacrawler";
final Path finalHtmlFile = createTempFilePath(stem, htmlx.getFormat());
final Path baseHtmlFile = createTempFilePath(stem, html.getFormat());
final Path baseSvgFile = createTempFilePath(stem, svg.getFormat());

final PropertyName commandName = getCommandName();
executeCommand(new SchemaTextRenderer(commandName), baseHtmlFile, html);
executeCommand(new DiagramRenderer(commandName, graphExecutorFactory), baseSvgFile, svg);

// Interleave HTML and SVG
try (final BufferedWriter finalHtmlFileWriter =
newBufferedWriter(finalHtmlFile, UTF_8, WRITE, CREATE, TRUNCATE_EXISTING);
final BufferedReader baseHtmlFileReader = newBufferedReader(baseHtmlFile, UTF_8);
final BufferedReader baseSvgFileReader = newBufferedReader(baseSvgFile, UTF_8)) {
String line;
while ((line = baseHtmlFileReader.readLine()) != null) {
if (svgInsertionPoint.matcher(line).matches()) {
insertSvg(finalHtmlFileWriter, baseSvgFileReader);
final Path tempDir = Files.createTempDirectory("schemacrawler");
final Path baseHtmlFile = tempDir.resolve("base." + html.getFormat());
final Path baseSvgFile = tempDir.resolve("base." + svg.getFormat());

try {
final PropertyName commandName = getCommandName();
executeCommand(new SchemaTextRenderer(commandName), baseHtmlFile, html);
executeCommand(new DiagramRenderer(commandName, graphExecutorFactory), baseSvgFile, svg);

// Interleave HTML and SVG, writing directly to the output writer
try (final BufferedWriter writer = new BufferedWriter(outputOptions.openNewOutputWriter());
final BufferedReader baseHtmlReader = newBufferedReader(baseHtmlFile, UTF_8)) {
final SVGInserter svgInserter = new SVGInserter(baseSvgFile);
boolean svgInserted = false;
String line;
while ((line = baseHtmlReader.readLine()) != null) {
if (!svgInserted && svgInsertionPoint.matcher(line).matches()) {
svgInserter.insert(writer);
svgInserted = true;
}
writer.append(line).append(System.lineSeparator());
}
if (!svgInserted) {
LOGGER.log(Level.WARNING, "SVG insertion point not found; embedded diagram is missing");
}
finalHtmlFileWriter.append(line).append(System.lineSeparator());
}
}

try (final Writer writer = outputOptions.openNewOutputWriter()) {
copy(newBufferedReader(finalHtmlFile, UTF_8), writer);
} finally {
try {
deleteIfExists(baseHtmlFile);
deleteIfExists(baseSvgFile);
deleteIfExists(tempDir);
} catch (final IOException e) {
LOGGER.log(Level.WARNING, "Could not delete temp files in " + tempDir, e);
}
}
} catch (final IOException e) {
throw new UncheckedIOException("Could not create embedded diagram", e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* SchemaCrawler
* http://www.schemacrawler.com
* Copyright (c) 2000-2026, Sualeh Fatehi <sualeh@hotmail.com>.
* All rights reserved.
* SPDX-License-Identifier: EPL-2.0
*/

package schemacrawler.tools.command.text.embeddeddiagram;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Path;
import java.util.regex.Pattern;
import us.fatehi.utility.ioresource.FileInputResource;

class SVGInserter {

private enum SvgParseState {
PREAMBLE,
SVG_BODY
}

private static final Pattern svgStart = Pattern.compile("<svg.*");

private final FileInputResource svgResource;

SVGInserter(final Path svgFilePath) {
requireNonNull(svgFilePath, "No SVG file path provided");
svgResource = new FileInputResource(svgFilePath);
}

void insert(final Writer writer) throws IOException {
requireNonNull(writer, "No writer provided");
writer.write(System.lineSeparator());
SvgParseState state = SvgParseState.PREAMBLE;
try (final BufferedReader svgReader = svgResource.openNewInputReader(UTF_8)) {
String line;
while ((line = svgReader.readLine()) != null) {
switch (state) {
case PREAMBLE:
if (svgStart.matcher(line).find()) {
writer.write("<svg");
writer.write(System.lineSeparator());
state = SvgParseState.SVG_BODY;
}
break;
case SVG_BODY:
writer.write(line);
writer.write(System.lineSeparator());
break;
}
}
}
writer.write(System.lineSeparator());
}
}
Loading