1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
package org.xwiki.platform.svg.internal; |
21 |
|
|
22 |
|
import java.io.File; |
23 |
|
import java.io.FileOutputStream; |
24 |
|
import java.io.IOException; |
25 |
|
import java.io.OutputStream; |
26 |
|
import java.io.StringReader; |
27 |
|
|
28 |
|
import javax.inject.Inject; |
29 |
|
import javax.inject.Named; |
30 |
|
import javax.inject.Singleton; |
31 |
|
import javax.servlet.http.HttpServletResponse; |
32 |
|
|
33 |
|
import org.apache.batik.transcoder.SVGAbstractTranscoder; |
34 |
|
import org.apache.batik.transcoder.TranscoderException; |
35 |
|
import org.apache.batik.transcoder.TranscoderInput; |
36 |
|
import org.apache.batik.transcoder.TranscoderOutput; |
37 |
|
import org.apache.batik.transcoder.image.PNGTranscoder; |
38 |
|
import org.apache.commons.io.FileUtils; |
39 |
|
import org.apache.commons.lang3.exception.ExceptionUtils; |
40 |
|
import org.slf4j.Logger; |
41 |
|
import org.xwiki.component.annotation.Component; |
42 |
|
import org.xwiki.container.Container; |
43 |
|
import org.xwiki.container.servlet.ServletResponse; |
44 |
|
import org.xwiki.model.reference.DocumentReference; |
45 |
|
import org.xwiki.model.reference.DocumentReferenceResolver; |
46 |
|
import org.xwiki.platform.svg.SVGRasterizer; |
47 |
|
import org.xwiki.resource.temporary.TemporaryResourceReference; |
48 |
|
import org.xwiki.resource.temporary.TemporaryResourceStore; |
49 |
|
|
50 |
|
|
51 |
|
@link |
52 |
|
|
53 |
|
@version |
54 |
|
@since |
55 |
|
|
56 |
|
@Component |
57 |
|
@Singleton |
|
|
| 100% |
Uncovered Elements: 0 (79) |
Complexity: 22 |
Complexity Density: 0.42 |
|
58 |
|
public class BatikSVGRasterizer implements SVGRasterizer |
59 |
|
{ |
60 |
|
private static final String TEMP_DIR_NAME = "svg"; |
61 |
|
|
62 |
|
private static final String RASTER_FILE_EXTENSION = ".png"; |
63 |
|
|
64 |
|
@Inject |
65 |
|
private Logger logger; |
66 |
|
|
67 |
|
@Inject |
68 |
|
private TemporaryResourceStore temporaryResourceStore; |
69 |
|
|
70 |
|
@Inject |
71 |
|
@Named("current") |
72 |
|
private DocumentReferenceResolver<String> currentDocumentResolver; |
73 |
|
|
74 |
|
@Inject |
75 |
|
private Container container; |
76 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (8) |
Complexity: 2 |
Complexity Density: 0.33 |
|
77 |
7 |
@Override... |
78 |
|
public File rasterizeToTemporaryFile(String content, int width, int height) throws IOException |
79 |
|
{ |
80 |
7 |
String fileName = getTemporaryFileName(content, width, height); |
81 |
7 |
TemporaryResourceReference reference = new TemporaryResourceReference(TEMP_DIR_NAME, fileName, null); |
82 |
7 |
File out = this.temporaryResourceStore.getTemporaryFile(reference); |
83 |
6 |
if (rasterizeToFile(content, out, width, height)) { |
84 |
3 |
return out; |
85 |
|
} |
86 |
3 |
return null; |
87 |
|
} |
88 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
89 |
5 |
@Override... |
90 |
|
public TemporaryResourceReference rasterizeToTemporaryResource(String content, int width, int height) |
91 |
|
throws IOException |
92 |
|
{ |
93 |
5 |
return rasterizeToTemporaryResource(content, width, height, getCurrentDocument()); |
94 |
|
} |
95 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (8) |
Complexity: 2 |
Complexity Density: 0.33 |
|
96 |
5 |
@Override... |
97 |
|
public TemporaryResourceReference rasterizeToTemporaryResource(String content, int width, int height, |
98 |
|
DocumentReference targetContext) throws IOException |
99 |
|
{ |
100 |
5 |
String fileName = getTemporaryFileName(content, width, height); |
101 |
5 |
TemporaryResourceReference reference = new TemporaryResourceReference(TEMP_DIR_NAME, fileName, targetContext); |
102 |
5 |
File out = this.temporaryResourceStore.getTemporaryFile(reference); |
103 |
5 |
if (rasterizeToFile(content, out, width, height)) { |
104 |
2 |
return reference; |
105 |
|
} |
106 |
3 |
return null; |
107 |
|
} |
108 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (15) |
Complexity: 3 |
Complexity Density: 0.27 |
|
109 |
3 |
@Override... |
110 |
|
public void rasterizeToResponse(String content, int width, int height) throws IOException |
111 |
|
{ |
112 |
3 |
if (!(this.container.getResponse() instanceof ServletResponse)) { |
113 |
1 |
return; |
114 |
|
} |
115 |
2 |
HttpServletResponse response = ((ServletResponse) this.container.getResponse()).getHttpServletResponse(); |
116 |
2 |
File result = rasterizeToTemporaryFile(content, width, height); |
117 |
2 |
if (result == null) { |
118 |
1 |
return; |
119 |
|
} |
120 |
1 |
response.setContentLength((int) result.length()); |
121 |
1 |
response.setContentType("image/png"); |
122 |
1 |
OutputStream os = response.getOutputStream(); |
123 |
1 |
FileUtils.copyFile(result, os); |
124 |
1 |
os.flush(); |
125 |
|
} |
126 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (21) |
Complexity: 8 |
Complexity Density: 0.53 |
|
127 |
12 |
private boolean rasterizeToFile(String content, File out, int width, int height) throws IOException... |
128 |
|
{ |
129 |
12 |
if (!out.getParentFile().exists() && !out.getParentFile().mkdirs()) { |
130 |
3 |
this.logger.debug("Failed to create temporary folder [{}].", out.getParentFile().getAbsolutePath()); |
131 |
3 |
return false; |
132 |
9 |
} else if (out.exists() && out.isFile()) { |
133 |
2 |
this.logger.debug("Reusing existing temporary raster image: {}", out.getAbsolutePath()); |
134 |
2 |
return true; |
135 |
|
} else { |
136 |
7 |
try (OutputStream fout = new FileOutputStream(out)) { |
137 |
6 |
this.logger.debug("Rasterizing to temp file: {}", out.getAbsolutePath()); |
138 |
6 |
TranscoderInput input = new TranscoderInput(new StringReader(content)); |
139 |
6 |
TranscoderOutput output = new TranscoderOutput(fout); |
140 |
6 |
boolean success = rasterize(input, output, width, height); |
141 |
6 |
if (!success) { |
142 |
3 |
out.delete(); |
143 |
|
} |
144 |
6 |
return success; |
145 |
|
} |
146 |
|
} |
147 |
|
} |
148 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (16) |
Complexity: 4 |
Complexity Density: 0.33 |
|
149 |
6 |
private boolean rasterize(TranscoderInput input, TranscoderOutput output, int width, int height)... |
150 |
|
{ |
151 |
6 |
PNGTranscoder transcoder = new PNGTranscoder(); |
152 |
|
|
153 |
6 |
if (width > 0) { |
154 |
3 |
transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, new Float(width)); |
155 |
|
} |
156 |
6 |
if (height > 0) { |
157 |
3 |
transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, new Float(height)); |
158 |
|
} |
159 |
|
|
160 |
|
|
161 |
6 |
transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_MAX_WIDTH, new Float(8192)); |
162 |
6 |
transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_MAX_HEIGHT, new Float(8192)); |
163 |
|
|
164 |
6 |
try { |
165 |
6 |
transcoder.transcode(input, output); |
166 |
3 |
return true; |
167 |
|
} catch (TranscoderException ex) { |
168 |
3 |
this.logger.warn("Failed to rasterize SVG image: {}", ExceptionUtils.getRootCauseMessage(ex)); |
169 |
|
} |
170 |
3 |
return false; |
171 |
|
} |
172 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
173 |
12 |
private String getTemporaryFileName(String content, int width, int height)... |
174 |
|
{ |
175 |
12 |
return Math.abs(content.hashCode()) + RASTER_FILE_EXTENSION; |
176 |
|
} |
177 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
178 |
5 |
private DocumentReference getCurrentDocument()... |
179 |
|
{ |
180 |
5 |
return this.currentDocumentResolver.resolve(""); |
181 |
|
} |
182 |
|
} |