Remove Image export support. It will be moved to the front end.

This commit is contained in:
Paulo Gustavo Veiga
2021-12-31 09:13:07 -08:00
parent ac7fd7e706
commit 71fefdd8c6
62 changed files with 4 additions and 30690 deletions

View File

@@ -21,15 +21,10 @@ package com.wisemapping.exporter;
import org.jetbrains.annotations.NotNull;
public enum ExportFormat {
SVG("image/svg+xml", "svg"),
JPG("image/jpeg", "jpg"),
PNG("image/png", "png"),
PDF("application/pdf", "pdf"),
FREEMIND("application/freemind", "mm"),
TEXT("text/plain", "txt"),
MICROSOFT_EXCEL("application/vnd.ms-excel", "xls"),
MICROSOFT_WORD("application/msword", "doc"),
OPEN_OFFICE_WRITER("application/vnd.oasis.opendocument.text", "odt"),
MINDJET("application/vnd.mindjet.mindmanager", "mmap"),
WISEMAPPING("application/wisemapping+xml", "wxml");

View File

@@ -31,13 +31,7 @@ public class ExportProperties {
}
public static ExportProperties create(final ExportFormat format) {
ExportProperties result;
if (format == ExportFormat.JPG || format == ExportFormat.PNG) {
result = new ImageProperties(format);
} else {
result = new GenericProperties(format);
}
return result;
return new GenericProperties(format);
}
public String getVersion() {
@@ -54,33 +48,4 @@ public class ExportProperties {
}
}
static public class ImageProperties extends ExportProperties {
private Size size;
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
ImageProperties(ExportFormat format) {
super(format);
}
public enum Size {
SMALL(100), MEDIUM(800), XMEDIUM(1024), LARGE(2048);
private final int width;
Size(int width) {
this.width = width;
}
public Float getWidth() {
return (float) width;
}
}
}
}

View File

@@ -19,19 +19,7 @@
package com.wisemapping.exporter;
import com.wisemapping.importer.VersionNumber;
import org.apache.batik.ext.awt.image.rendered.TileCache;
import org.apache.batik.parser.AWTTransformProducer;
import org.apache.batik.parser.ParseException;
import org.apache.batik.parser.TransformListParser;
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.commons.io.IOUtils;
import org.apache.fop.svg.PDFTranscoder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.w3c.dom.*;
@@ -56,14 +44,9 @@ import java.util.regex.Pattern;
public class ExporterFactory {
static {
// Try to prevent OOM.
TileCache.setSize(0);
}
private static final String GROUP_NODE_NAME = "g";
private static final String IMAGE_NODE_NAME = "image";
private static final int MANGING = 50;
private static final String UTF_8_CHARSET_NAME = "UTF-8";
private final File baseImgDir;
public ExporterFactory(@NotNull final ServletContext servletContext) {
@@ -74,81 +57,16 @@ public class ExporterFactory {
this.baseImgDir = baseImgDir;
}
public void export(@NotNull ExportProperties properties, @Nullable String xml, @NotNull OutputStream output, @Nullable String mapSvg) throws ExportException, IOException, TranscoderException {
public void export(@NotNull ExportProperties properties, @Nullable String xml, @NotNull OutputStream output, @Nullable String mapSvg) throws ExportException, IOException {
final ExportFormat format = properties.getFormat();
switch (format) {
case PNG: {
// Create a JPEG transcoder
final Transcoder transcoder = new PNGTranscoder();
final ExportProperties.ImageProperties imageProperties =
(ExportProperties.ImageProperties) properties;
final ExportProperties.ImageProperties.Size size = imageProperties.getSize();
transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, size.getWidth());
// Create the transcoder input.
final String svgString = normalizeSvg(mapSvg);
final CharArrayReader reader = new CharArrayReader(svgString.toCharArray());
final TranscoderInput input = new TranscoderInput(reader);
TranscoderOutput transcoderOutput = new TranscoderOutput(output);
// Save the image.
transcoder.transcode(input, transcoderOutput);
reader.close();
break;
}
case JPG: {
// Create a JPEG transcoder
final Transcoder transcoder = new JPEGTranscoder();
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, .99f);
final ExportProperties.ImageProperties imageProperties =
(ExportProperties.ImageProperties) properties;
final ExportProperties.ImageProperties.Size size = imageProperties.getSize();
transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, size.getWidth());
// Create the transcoder input.
final String svgString = normalizeSvg(mapSvg);
CharArrayReader reader = new CharArrayReader(svgString.toCharArray());
final TranscoderInput input = new TranscoderInput(reader);
TranscoderOutput trascoderOutput = new TranscoderOutput(output);
// Save the image.
transcoder.transcode(input, trascoderOutput);
reader.close();
break;
}
case PDF: {
// Create a JPEG transcoder
final Transcoder transcoder = new PDFTranscoder();
// Create the transcoder input.
final String svgString = normalizeSvg(mapSvg);
CharArrayReader reader = new CharArrayReader(svgString.toCharArray());
final TranscoderInput input = new TranscoderInput(reader);
TranscoderOutput trascoderOutput = new TranscoderOutput(output);
// Save the image.
transcoder.transcode(input, trascoderOutput);
reader.close();
break;
}
case SVG: {
final String svgString = normalizeSvg(mapSvg);
output.write(svgString.getBytes(StandardCharsets.UTF_8));
break;
}
case TEXT: {
final Exporter exporter = XSLTExporter.create(XSLTExporter.Type.TEXT);
exporter.export(xml.getBytes(StandardCharsets.UTF_8), output);
break;
}
case OPEN_OFFICE_WRITER: {
final Exporter exporter = XSLTExporter.create(XSLTExporter.Type.OPEN_OFFICE);
exporter.export(xml.getBytes(StandardCharsets.UTF_8), output);
break;
}
case MICROSOFT_EXCEL: {
final Exporter exporter = XSLTExporter.create(XSLTExporter.Type.MICROSOFT_EXCEL);
exporter.export(xml.getBytes(StandardCharsets.UTF_8), output);
@@ -173,54 +91,6 @@ public class ExporterFactory {
output.close();
}
private String normalizeSvg(@NotNull String svgXml) throws ExportException {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final DocumentBuilder documentBuilder = factory.newDocumentBuilder();
if (!svgXml.contains("xmlns:xlink=\"http://www.w3.org/1999/xlink\"")) {
svgXml = svgXml.replaceFirst("<svg ", "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
}
if (!svgXml.contains("xmlns=\"http://www.w3.org/2000/svg\"")) {
svgXml = svgXml.replaceFirst("<svg ", "<svg xmlns=\"http://www.w3.org/2000/svg\" ");
}
// Hacks for some legacy cases ....
svgXml = svgXml.replaceAll("NaN,", "0");
svgXml = svgXml.replaceAll(",NaN", "0");
// Bratik do not manage nbsp properly.
svgXml = svgXml.replaceAll(Pattern.quote("&nbsp;"), " ");
Document document;
try {
final Reader in = new CharArrayReader(svgXml.toCharArray());
final InputSource is = new InputSource(in);
document = documentBuilder.parse(is);
} catch (SAXException e) {
// It must be a corrupted SVG format. Try to hack it and try again ...
svgXml = svgXml.replaceAll("<image([^>]+)>", "<image$1/>");
svgXml = svgXml.replaceAll("\u001B", "");
final Reader in = new CharArrayReader(svgXml.toCharArray());
final InputSource is = new InputSource(in);
document = documentBuilder.parse(is);
}
resizeSVG(document);
final Node child = document.getFirstChild();
inlineImages(document, (Element) child);
return domToString(document);
} catch (ParserConfigurationException | TransformerException | SAXException | IOException e) {
throw new ExportException(e);
}
}
private static String domToString(@NotNull Document document) throws TransformerException {
DOMSource domSource = new DOMSource(document);
@@ -344,76 +214,4 @@ public class ExporterFactory {
}
}
}
private static void resizeSVG(@NotNull Document document) throws ExportException {
try {
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("/svg/g/rect");
NodeList nl = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
final int length = nl.getLength();
double maxX = 0, minX = 0, minY = 0, maxY = 0;
for (int i = 0; i < length; i++) {
final Element rectElem = (Element) nl.item(i);
final Element gElem = (Element) rectElem.getParentNode();
final TransformListParser p = new TransformListParser();
final AWTTransformProducer tp = new AWTTransformProducer();
p.setTransformListHandler(tp);
p.parse(gElem.getAttribute("transform"));
final AffineTransform transform = tp.getAffineTransform();
double yPos = transform.getTranslateY();
if (yPos > 0) {
yPos += Double.parseDouble(rectElem.getAttribute("height"));
}
maxY = maxY < yPos ? yPos : maxY;
minY = minY > yPos ? yPos : minY;
double xPos = transform.getTranslateX();
if (xPos > 0) {
xPos += Double.parseDouble(rectElem.getAttribute("width"));
}
maxX = maxX < xPos ? xPos : maxX;
minX = minX > xPos ? xPos : minX;
}
// Add some extra margin ...
maxX += MANGING;
minX += -MANGING;
maxY += MANGING;
minY += -MANGING;
// Calculate dimentions ...
final double width = maxX + Math.abs(minX);
final double height = maxY + Math.abs(minY);
// Finally, update centers ...
final Element svgNode = (Element) document.getFirstChild();
svgNode.setAttribute("viewBox", minX + " " + minY + " " + width + " " + height);
svgNode.setAttribute("width", Double.toString(width));
svgNode.setAttribute("height", Double.toString(height));
svgNode.setAttribute("preserveAspectRatio", "xMinYMin");
} catch (XPathExpressionException | ParseException | NumberFormatException | DOMException e) {
throw new ExportException(e);
}
}
private static String[] getTransformUnit(NamedNodeMap groupAttributes) {
final String value = groupAttributes.getNamedItem("transform").getNodeValue();
final int pos = value.indexOf("translate");
final int initTranslate = value.indexOf("(", pos);
final int endTranslate = value.indexOf(")", pos);
final String transate = value.substring(initTranslate + 1, endTranslate);
return transate.contains(",") ? transate.split(",") : transate.split(" ");
}
}

View File

@@ -42,55 +42,7 @@ public class TransformerController extends BaseController {
private static final String PARAM_WISE_MAP_XML = "mapXml";
private static final String PARAM_FILENAME = "filename";
@RequestMapping(method = RequestMethod.POST, value = "/transform", produces = {"application/pdf"}, consumes = {"image/svg+xml"})
@ResponseBody
public ModelAndView transformPdf(@RequestBody @Nullable final String content) {
final Map<String, Object> values = new HashMap<String, Object>();
if (content == null || content.length() == 0) {
throw new IllegalArgumentException("Body can not be null.");
}
values.put("content", content);
return new ModelAndView("transformViewPdf", values);
}
@RequestMapping(method = RequestMethod.POST, value = "/transform", produces = {"image/svg+xml"}, consumes = {"image/svg+xml"})
@ResponseBody
public ModelAndView transformSvg(@RequestBody @Nullable final String content) {
final Map<String, Object> values = new HashMap<String, Object>();
if (content == null || content.length() == 0) {
throw new IllegalArgumentException("Body can not be null.");
}
values.put("content", content);
return new ModelAndView("transformViewSvg", values);
}
@RequestMapping(method = RequestMethod.POST, value = "/transform", produces = {"image/png"}, consumes = {"image/svg+xml"})
@ResponseBody
public ModelAndView transformPng(@RequestBody @Nullable final String content) {
final Map<String, Object> values = new HashMap<String, Object>();
if (content == null || content.length() == 0) {
throw new IllegalArgumentException("Body can not be null.");
}
values.put("content", content);
values.put("imageSize", ExportProperties.ImageProperties.Size.LARGE);
return new ModelAndView("transformViewPng", values);
}
@RequestMapping(method = RequestMethod.POST, value = "/transform", produces = {"image/jpeg"}, consumes = {"image/svg+xml"})
@ResponseBody
public ModelAndView transformJpeg(@RequestBody @Nullable final String content) throws IOException {
final Map<String, Object> values = new HashMap<String, Object>();
if (content == null || content.length() == 0) {
throw new IllegalArgumentException("Body can not be null.");
}
values.put("content", content);
values.put("imageSize", ExportProperties.ImageProperties.Size.LARGE);
return new ModelAndView("transformViewJpeg", values);
}
@RequestMapping(method = RequestMethod.POST, value = "/transform", produces = {"application/freemind"}, consumes = {"application/xml"})
@RequestMapping(method = RequestMethod.POST, value = "/transform", produces = {"application/freemind"}, consumes = {"application/xml"})
@ResponseBody
public ModelAndView transformFreemind(@RequestBody @Nullable final String content) throws IOException {
final Map<String, Object> values = new HashMap<String, Object>();
@@ -100,40 +52,4 @@ public class TransformerController extends BaseController {
values.put("content", content);
return new ModelAndView("transformViewFreemind", values);
}
@RequestMapping(method = RequestMethod.POST, value = "/transform", consumes = {"application/x-www-form-urlencoded"})
public ModelAndView transform(@NotNull HttpServletRequest request) throws IOException {
final String svg = request.getParameter(PARAM_SVG_XML);
final String mapXml = request.getParameter(PARAM_WISE_MAP_XML);
final String filename = request.getParameter(PARAM_FILENAME);
// Obtains transformation type based on the last part of the URL ...
final String requestURI = request.getRequestURI();
final String format = requestURI.substring(requestURI.lastIndexOf(".") + 1);
final ExportFormat exportFormat = ExportFormat.valueOf(format.toUpperCase());
ModelAndView result;
switch (exportFormat) {
case PNG:
result = this.transformPng(svg);
break;
case JPG:
result = this.transformJpeg(svg);
break;
case PDF:
result = this.transformPdf(svg);
break;
case SVG:
result = this.transformSvg(svg);
break;
default:
throw new IllegalArgumentException("Unsupported export format");
}
if (filename != null) {
result.getModelMap().put("filename", filename);
}
return result;
}
}

View File

@@ -63,10 +63,6 @@ public class TransformView extends AbstractView {
// Build format properties ...
final ExportProperties properties = ExportProperties.create(exportFormat);
if (properties instanceof ExportProperties.ImageProperties) {
final ExportProperties.ImageProperties imageProperties = (ExportProperties.ImageProperties) properties;
imageProperties.setSize(ExportProperties.ImageProperties.Size.LARGE);
}
if (version != null) {
properties.setVersion(version);
}
@@ -93,7 +89,7 @@ public class TransformView extends AbstractView {
final Object mindmap = viewMap.get("mindmap");
final StreamResult result = new StreamResult(outputStream);
jaxbMarshaller.marshal(mindmap, result);
} else if (exportFormat == ExportFormat.MICROSOFT_EXCEL || exportFormat == ExportFormat.TEXT || exportFormat == ExportFormat.OPEN_OFFICE_WRITER || exportFormat == ExportFormat.MINDJET) {
} else if (exportFormat == ExportFormat.MICROSOFT_EXCEL || exportFormat == ExportFormat.TEXT || exportFormat == ExportFormat.MINDJET) {
response.setContentType(String.format("%s; charset=%s", contentType, DEFAULT_ENCODING));
factory.export(properties, content, outputStream, null);