9 Commits
v1.0 ... v2.0

Author SHA1 Message Date
Paulo Gustavo Veiga
9a45d0402a Fix stupid mistake. 2011-04-06 17:51:16 -03:00
Paulo Gustavo Veiga
c5aa23dbc4 Merge branch 'master' of ssh://wisemapping.com/var/git-repos/wise-source
Conflicts:
	wise-webapp/src/main/java/com/wisemapping/exporter/ExporterFactory.java
2011-04-06 17:34:17 -03:00
Paulo Gustavo Veiga
0420cc1d03 Replace by dom. 2011-04-06 17:27:18 -03:00
Pablo Luna
c9ff2e23d5 adding export test that fails on local 2011-04-06 20:43:43 +01:00
Pablo Luna
5318e29df5 fixing print and export 2011-04-06 20:36:57 +01:00
Pablo Luna
1a69d0b3c3 fixing print 2011-04-06 19:45:23 +01:00
Pablo Luna
002dba3094 fixing print 2011-04-06 19:05:47 +01:00
Pablo Luna
d2b8c3fd7c fixing print 2011-04-06 18:01:53 +01:00
Pablo Luna
bb156c4b55 fixing print 2011-04-06 17:58:32 +01:00
6 changed files with 153 additions and 86 deletions

View File

@@ -18,6 +18,7 @@
package com.wisemapping.controller; package com.wisemapping.controller;
import com.wisemapping.exporter.ExportException;
import com.wisemapping.exporter.ExportFormat; import com.wisemapping.exporter.ExportFormat;
import com.wisemapping.exporter.ExporterFactory; import com.wisemapping.exporter.ExporterFactory;
import com.wisemapping.model.MindMap; import com.wisemapping.model.MindMap;
@@ -29,13 +30,20 @@ import org.apache.batik.transcoder.TranscoderException;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
import org.xml.sax.SAXException;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.TransformerException;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
public class ExportController extends BaseMultiActionController { public class ExportController extends BaseMultiActionController {
private static final String IMG_EXPORT_FORMAT = "IMG_EXPORT_FORMAT"; private static final String IMG_EXPORT_FORMAT = "IMG_EXPORT_FORMAT";
@@ -123,7 +131,7 @@ public class ExportController extends BaseMultiActionController {
baseUrl = "http://www.wisemapping.com/images"; baseUrl = "http://www.wisemapping.com/images";
} else { } else {
final ServletContext servletContext = this.getServletContext(); final ServletContext servletContext = this.getServletContext();
baseUrl = "file://" + servletContext.getRealPath("/icons/"); baseUrl = "file://" + servletContext.getRealPath("/icons/")+"/";
} }
properties.setBaseImagePath(baseUrl); properties.setBaseImagePath(baseUrl);
} }
@@ -135,19 +143,46 @@ public class ExportController extends BaseMultiActionController {
int mindmapId = Integer.parseInt(mapIdStr); int mindmapId = Integer.parseInt(mapIdStr);
final MindmapService service = getMindmapService(); final MindmapService service = getMindmapService();
final MindMap mindMap = service.getMindmapById(mindmapId); final MindMap mindMap = service.getMindmapById(mindmapId);
final String mapSvg = request.getParameter(MAP_SVG_PARAMETER);
return new ModelAndView("mindmapPrint", "mindmap", mindMap); final ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
exportImage(response, mapSvg, bos, false);
} catch (Throwable e) {
logger.error("Unexpexted error generating the image", e);
logger.error("map: "+mapSvg);
}
BASE64Encoder encoder = new BASE64Encoder();
String content = encoder.encode(bos.toByteArray());
final String exportContent = "data:image/png;base64,"+content;
bos.close();
ModelAndView view = new ModelAndView("mindmapPrint", "mindmap", mindMap);
view.addObject(MAP_SVG_PARAMETER, exportContent);
return view;
} }
public ModelAndView image(HttpServletRequest request, HttpServletResponse response) throws TranscoderException, IOException, JAXBException { public ModelAndView image(HttpServletRequest request, HttpServletResponse response) throws TranscoderException, IOException, JAXBException {
try {
logger.info("Export Controller: generating image WiseMap action"); logger.info("Export Controller: generating image WiseMap action");
final String mapIdStr = request.getParameter(MAP_ID_PARAMETER); final String mapIdStr = request.getParameter(MAP_ID_PARAMETER);
final String mapSvg = request.getParameter(MAP_SVG_PARAMETER); final String mapSvg = request.getParameter(MAP_SVG_PARAMETER);
try {
final ServletOutputStream outputStream = response.getOutputStream();
final MindmapService service = getMindmapService(); exportImage(response, mapSvg, outputStream, true);
} catch (Throwable e) {
logger.error("Unexpexted error generating the image", e);
logger.error("map: "+mapSvg);
}
return null;
}
private void exportImage(HttpServletResponse response, String mapSvg, OutputStream outputStream, boolean setOutput) throws TranscoderException, IOException, ParserConfigurationException, SAXException, XMLStreamException, TransformerException, JAXBException, ExportException {
//Image Format //Image Format
ExportFormat imageFormat = ExportFormat.PNG; ExportFormat imageFormat = ExportFormat.PNG;
@@ -160,16 +195,10 @@ public class ExportController extends BaseMultiActionController {
setBaseBaseImgUrl(imageFormat, imageProperties); setBaseBaseImgUrl(imageFormat, imageProperties);
// Set format content type... // Set format content type...
if(setOutput)
response.setContentType(imageFormat.getContentType()); response.setContentType(imageFormat.getContentType());
// Write content ... // Write content ...
final ServletOutputStream outputStream = response.getOutputStream();
ExporterFactory.export(imageProperties, null, outputStream, mapSvg); ExporterFactory.export(imageProperties, null, outputStream, mapSvg);
} catch (Throwable e) {
logger.error("Unexpexted error generating the image", e);
}
return null;
} }
} }

View File

@@ -50,7 +50,9 @@ public class ExporterFactory {
private static final String RECT_NODE_NAME = "rect"; private static final String RECT_NODE_NAME = "rect";
private static final String IMAGE_NODE_NAME = "image"; private static final String IMAGE_NODE_NAME = "image";
private ExporterFactory() {
private ExporterFactory() throws ParserConfigurationException {
} }
public static void export(@NotNull ExportProperties properties, @Nullable MindMap map, @NotNull OutputStream output, @NotNull String mapSvg) throws TranscoderException, IOException, ParserConfigurationException, SAXException, XMLStreamException, TransformerException, JAXBException, ExportException { public static void export(@NotNull ExportProperties properties, @Nullable MindMap map, @NotNull OutputStream output, @NotNull String mapSvg) throws TranscoderException, IOException, ParserConfigurationException, SAXException, XMLStreamException, TransformerException, JAXBException, ExportException {
@@ -67,10 +69,10 @@ public class ExporterFactory {
transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, size.getWidth()); transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, size.getWidth());
// Create the transcoder input. // Create the transcoder input.
char[] xml = convertBrowserSvgToXmlSvg(mapSvg); final Document document = normalizeSvg(mapSvg, imgPath);
xml = normalizeSvg(xml, imgPath); final String svgString = domToString(document);
final CharArrayReader is = new CharArrayReader(xml); final TranscoderInput input = new TranscoderInput(new CharArrayReader(svgString.toCharArray()));
TranscoderInput input = new TranscoderInput(is);
TranscoderOutput trascoderOutput = new TranscoderOutput(output); TranscoderOutput trascoderOutput = new TranscoderOutput(output);
// Save the image. // Save the image.
@@ -88,10 +90,10 @@ public class ExporterFactory {
transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, size.getWidth()); transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, size.getWidth());
// Create the transcoder input. // Create the transcoder input.
final char[] xml = convertBrowserSvgToXmlSvg(mapSvg); final Document document = normalizeSvg(mapSvg, imgPath);
char[] svgXml = normalizeSvg(xml, imgPath); final String svgString = domToString(document);
final CharArrayReader is = new CharArrayReader(svgXml); final TranscoderInput input = new TranscoderInput(new CharArrayReader(svgString.toCharArray()));
TranscoderInput input = new TranscoderInput(is);
TranscoderOutput trascoderOutput = new TranscoderOutput(output); TranscoderOutput trascoderOutput = new TranscoderOutput(output);
// Save the image. // Save the image.
@@ -103,10 +105,10 @@ public class ExporterFactory {
final Transcoder transcoder = new PDFTranscoder(); final Transcoder transcoder = new PDFTranscoder();
// Create the transcoder input. // Create the transcoder input.
final char[] xml = convertBrowserSvgToXmlSvg(mapSvg); final Document document = normalizeSvg(mapSvg, imgPath);
char[] svgXml = normalizeSvg(xml, imgPath); final String svgString = domToString(document);
final CharArrayReader is = new CharArrayReader(svgXml); final TranscoderInput input = new TranscoderInput(new CharArrayReader(svgString.toCharArray()));
TranscoderInput input = new TranscoderInput(is);
TranscoderOutput trascoderOutput = new TranscoderOutput(output); TranscoderOutput trascoderOutput = new TranscoderOutput(output);
// Save the image. // Save the image.
@@ -114,9 +116,8 @@ public class ExporterFactory {
break; break;
} }
case SVG: { case SVG: {
final char[] xml = convertBrowserSvgToXmlSvg(mapSvg); final Document dom = normalizeSvg(mapSvg, imgPath);
char[] svgXml = normalizeSvg(xml, imgPath); output.write(domToString(dom).getBytes("UTF-8"));
output.write(new String(svgXml).getBytes("UTF-8"));
break; break;
} }
case FREEMIND: { case FREEMIND: {
@@ -129,30 +130,49 @@ public class ExporterFactory {
} }
} }
private static char[] normalizeSvg(final char[] svgXml, final String imgBaseUrl) throws XMLStreamException, ParserConfigurationException, IOException, SAXException, TransformerException { private static Document normalizeSvg(@NotNull String svgXml, final String imgBaseUrl) throws XMLStreamException, ParserConfigurationException, IOException, SAXException, TransformerException {
final Reader in = new CharArrayReader(svgXml);
// Load document ... final DocumentBuilder documentBuilder = getDocumentBuilder();
svgXml = svgXml.replaceFirst("<svg ", "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
Document document;
try {
final Reader in = new CharArrayReader(svgXml.toCharArray());
final InputSource is = new InputSource(in); 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/>");
final Reader in = new CharArrayReader(svgXml.toCharArray());
final InputSource is = new InputSource(in);
document = documentBuilder.parse(is);
}
fitSvg(document);
fixImageTagHref(document, imgBaseUrl);
return document;
}
private static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = factory.newDocumentBuilder(); return factory.newDocumentBuilder();
}
final Document svgDocument = documentBuilder.parse(is); private static String domToString(@NotNull Document document) throws TransformerException {
DOMSource domSource = new DOMSource(document);
fitSvg(svgDocument);
fixImageTagHref(svgDocument, imgBaseUrl);
DOMSource domSource = new DOMSource(svgDocument);
// Save document ...
// Create a string writer // Create a string writer
final CharArrayWriter outDocument = new CharArrayWriter(); final CharArrayWriter result = new CharArrayWriter();
// Create the result stream for the transform // Create the stream stream for the transform
StreamResult result = new StreamResult(outDocument); StreamResult stream = new StreamResult(result);
// Create a Transformer to serialize the document // Create a Transformer to serialize the document
TransformerFactory tFactory = TransformerFactory.newInstance(); TransformerFactory tFactory = TransformerFactory.newInstance();
@@ -160,19 +180,18 @@ public class ExporterFactory {
Transformer transformer = tFactory.newTransformer(); Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty("indent", "yes"); transformer.setOutputProperty("indent", "yes");
// Transform the document to the result stream // Transform the document to the stream stream
transformer.transform(domSource, result); transformer.transform(domSource, stream);
return outDocument.toCharArray();
return result.toString();
} }
private static void fixImageTagHref(Document svgDocument, String imgBaseUrl) { private static void fixImageTagHref(Document document, String imgBaseUrl) {
final Node child = svgDocument.getFirstChild(); final Node child = document.getFirstChild();
fixImageTagHref((Element) child, imgBaseUrl); fixImageTagHref(document, (Element) child, imgBaseUrl);
} }
private static void fixImageTagHref(Element element, String imgBaseUrl) { private static void fixImageTagHref(@NotNull Document document, @NotNull Element element, String imgBaseUrl) {
final NodeList list = element.getChildNodes(); final NodeList list = element.getChildNodes();
@@ -181,7 +200,7 @@ public class ExporterFactory {
// find all groups // find all groups
if (GROUP_NODE_NAME.equals(node.getNodeName())) { if (GROUP_NODE_NAME.equals(node.getNodeName())) {
// Must continue looking .... // Must continue looking ....
fixImageTagHref((Element) node, imgBaseUrl); fixImageTagHref(document, (Element) node, imgBaseUrl);
} else if (IMAGE_NODE_NAME.equals(node.getNodeName())) { } else if (IMAGE_NODE_NAME.equals(node.getNodeName())) {
@@ -196,11 +215,12 @@ public class ExporterFactory {
// Hack for backward compatibility . This can be removed in 2012. :) // Hack for backward compatibility . This can be removed in 2012. :)
String imgPath; String imgPath;
if (imgUrl.contains("images")) { if (imgUrl.contains("images")) {
imgPath = imgBaseUrl + "../images/" + imgUrl; imgPath = imgBaseUrl + "../images/" + iconName;
} else { } else {
imgPath = imgBaseUrl + imgUrl; imgPath = imgBaseUrl + imgUrl;
} }
elem.setAttribute("xlink:href", imgPath); elem.setAttribute("xlink:href", imgPath);
elem.appendChild(document.createTextNode(" "));
} }
} }
} }
@@ -279,15 +299,4 @@ public class ExporterFactory {
return transate.split(","); return transate.split(",");
} }
@NotNull
static private char[] convertBrowserSvgToXmlSvg(@NotNull String mapSvg)
throws IOException, JAXBException {
String result = "<?xml version='1.0' encoding='UTF-8'?>\n" + mapSvg;
// Add namespace...
result = result.replaceFirst("<svg ", "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
result = result.replaceAll("/<image([^>]+)//?>/", "<image$1></image>");
return result.toCharArray();
}
} }

View File

@@ -220,9 +220,9 @@
rel="moodalbox 600px 400px" title="<spring:message code="EXPORT_DETAILS"/>"> rel="moodalbox 600px 400px" title="<spring:message code="EXPORT_DETAILS"/>">
<spring:message code="EXPORT"/> <spring:message code="EXPORT"/>
</a>--%> </a>--%>
<a href="javascript:printMap(${mindmap.id});"> <%--<a href="javascript:printMap(${mindmap.id});">
<spring:message code="PRINT"/> <spring:message code="PRINT"/>
</a> </a>--%>
</div> </div>
</div> </div>
</td> </td>

View File

@@ -9,10 +9,6 @@
%> %>
<!DOCTYPE HTML PUBLIC> <!DOCTYPE HTML PUBLIC>
<%@ include file="/jsp/init.jsp" %> <%@ include file="/jsp/init.jsp" %>
<c:url value="export.htm" var="exportUrl">
<c:param name="action" value="image"/>
<c:param name="mapId" value="${mindmap.id}"/>
</c:url>
<html> <html>
<head> <head>
<title> <title>
@@ -26,7 +22,7 @@
<div id="headerTitle">${mindmap.title}<span id="headerSubTitle">&nbsp;(<%=todayString%>)</span></div> <div id="headerTitle">${mindmap.title}<span id="headerSubTitle">&nbsp;(<%=todayString%>)</span></div>
</div> </div>
<center> <center>
<img src="${exportUrl}" alt="${mindmap.title}"/> <img src="${mapSvg}" alt="${mindmap.title}"/>
</center> </center>
</body> </body>
</html> </html>

View File

View File

@@ -0,0 +1,33 @@
<svg preserveAspectRatio="none" viewBox="-560 -98.69999999999999 1120 197.39999999999998" height="282" width="1600"
id="workspace" focusable="true">
<path fill-opacity="1.0999999999999999" visibility="visible" d="M0,0 C-38,0 -54,-40 -92,-40"
stroke-opacity="1.0999999999999999" stroke="#495879" stroke-width="1px" style="fill: none;"></path>
<g visibility="visible" transform="translate(-23, -17) scale(1)" height="100" width="100" focusable="true"
preserveAspectRatio="none">
<rect style="cursor: default;" fill-opacity="0" stroke-opacity="0" fill="#dbe2e6" stroke="#77555a"
stroke-width="1px" y="-3" x="-2" ry="6.1499999999999995" rx="6.1499999999999995" height="41"
width="50"></rect>
<rect style="cursor: default;" stroke="#023BB9" fill="#f7f7f7" stroke-width="0.5px" y="0" x="0" ry="5.25"
rx="5.25" height="35" width="46"></rect>
<text visibility="visible" x="18" y="19" style="cursor: default;" fill="#023BB9" font-weight="bold"
font-style="normal" font-size="13.4375" font-family="verdana" focusable="true">t
</text>
</g>
<g fill-opacity="1.0999999999999999" stroke-opacity="1.0999999999999999" visibility="visible"
transform="translate(-174, -51) scale(1)" height="100" width="100" focusable="true" preserveAspectRatio="none">
<rect style="cursor: move;" fill-opacity="1" stroke-opacity="1" fill="#c7d8ff" stroke="#77555a"
stroke-width="1px" y="-3" x="-2" ry="4.2" rx="4.2" height="28" width="88"></rect>
<rect visibility="visible" style="cursor: move;" fill="#E0E5EF" stroke="#023BB9" stroke-width="0.5px" y="0"
x="0" ry="3.3" rx="3.3" height="22" width="84"></rect>
<text fill-opacity="1.0999999999999999" stroke-opacity="1.0999999999999999" visibility="visible" x="22" y="12"
style="cursor: move;" fill="#525c61" font-weight="normal" font-style="normal" font-size="10.75"
font-family="verdana" focusable="true">Main Topic
</text>
<ellipse fill-opacity="1.0999999999999999" stroke-opacity="1.0999999999999999" stroke="#023BB9"
visibility="hidden" style="cursor: default;" fill="#E0E5EF" stroke-width="1px" cy="3" cx="3" ry="3"
rx="3" height="6" width="6"></ellipse>
<g transform="translate(8, 2) scale(1)" height="12" width="14" focusable="true" preserveAspectRatio="none">
<image x="2" y="0" height="12" width="12" href="../icons/onoff_clock.png">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB