Skip to content

Commit 440992d

Browse files
dmitry.radchukEugene Bochilo
authored andcommitted
Replaced reflection instances creation with functional interfaces
DEVSIX-5739
1 parent aa0c6fe commit 440992d

File tree

5 files changed

+161
-175
lines changed

5 files changed

+161
-175
lines changed

svg/src/main/java/com/itextpdf/svg/exceptions/SvgExceptionMessageConstant.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public final class SvgExceptionMessageConstant {
5454
+ "coordinates";
5555
public static final String COULD_NOT_DETERMINE_MIDDLE_POINT_OF_ELLIPTICAL_ARC = "Could not determine the middle "
5656
+ "point of the ellipse traced by this elliptical arc";
57-
public static final String COULD_NOT_INSTANTIATE = "Could not instantiate Renderer for tag {0}";
5857
public static final String CURVE_TO_EXPECTS_FOLLOWING_PARAMETERS_GOT_0 = "(x1 y1 x2 y2 x y)+ parameters are "
5958
+ "expected for curves. Got: {0}";
6059
public static final String DRAW_NO_DRAW = "The renderer cannot be drawn.";

svg/src/main/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererFactory.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ This file is part of the iText (R) project.
4949
import com.itextpdf.svg.exceptions.SvgProcessingException;
5050
import com.itextpdf.svg.renderers.INoDrawSvgNodeRenderer;
5151
import com.itextpdf.svg.renderers.ISvgNodeRenderer;
52+
import com.itextpdf.svg.renderers.factories.DefaultSvgNodeRendererMapper.ISvgNodeRendererCreator;
5253
import com.itextpdf.svg.renderers.impl.DefsSvgNodeRenderer;
5354

5455
import java.util.Collection;
@@ -65,8 +66,8 @@ This file is part of the iText (R) project.
6566
*/
6667
public class DefaultSvgNodeRendererFactory implements ISvgNodeRendererFactory {
6768

68-
private Map<String, Class<? extends ISvgNodeRenderer>> rendererMap = new HashMap<>();
69-
private Collection<String> ignoredTags = new HashSet<>();
69+
private final Map<String, ISvgNodeRendererCreator> rendererMap = new HashMap<>();
70+
private final Collection<String> ignoredTags = new HashSet<>();
7071

7172
/**
7273
* Default constructor with default {@link ISvgNodeRenderer} creation logic.
@@ -85,21 +86,16 @@ public ISvgNodeRenderer createSvgNodeRendererForTag(IElementNode tag, ISvgNodeRe
8586
throw new SvgProcessingException(SvgExceptionMessageConstant.TAG_PARAMETER_NULL);
8687
}
8788

88-
try {
89-
Class<? extends ISvgNodeRenderer> clazz = rendererMap.get(tag.name());
89+
final ISvgNodeRendererCreator svgNodeRendererCreator = rendererMap.get(tag.name());
9090

91-
if (clazz == null) {
92-
Logger logger = LoggerFactory.getLogger(this.getClass());
93-
logger.warn(MessageFormatUtil.format(SvgLogMessageConstant.UNMAPPED_TAG, tag.name()));
94-
return null;
95-
}
96-
97-
result = (ISvgNodeRenderer) rendererMap.get(tag.name()).newInstance();
98-
} catch (ReflectiveOperationException ex) {
99-
throw new SvgProcessingException(SvgExceptionMessageConstant.COULD_NOT_INSTANTIATE, ex)
100-
.setMessageParams(tag.name());
91+
if (svgNodeRendererCreator == null) {
92+
Logger logger = LoggerFactory.getLogger(this.getClass());
93+
logger.warn(MessageFormatUtil.format(SvgLogMessageConstant.UNMAPPED_TAG, tag.name()));
94+
return null;
10195
}
10296

97+
result = svgNodeRendererCreator.create();
98+
10399
// DefsSvgNodeRenderer should not have parental relationship with any renderer, it only serves as a storage
104100
if (parent != null && !(result instanceof INoDrawSvgNodeRenderer) && !(parent instanceof DefsSvgNodeRenderer)) {
105101
result.setParent(parent);

svg/src/main/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererMapper.java

Lines changed: 125 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ This file is part of the iText (R) project.
6767
import com.itextpdf.svg.renderers.impl.UseSvgNodeRenderer;
6868

6969
import java.util.Collection;
70+
import java.util.Collections;
7071
import java.util.HashMap;
7172
import java.util.HashSet;
7273
import java.util.Map;
@@ -77,103 +78,139 @@ This file is part of the iText (R) project.
7778
*/
7879
class DefaultSvgNodeRendererMapper {
7980

81+
private static final String CLIP_PATH_LC = SvgConstants.Tags.CLIP_PATH.toLowerCase();
82+
private static final String LINEAR_GRADIENT_LC = SvgConstants.Tags.LINEAR_GRADIENT.toLowerCase();
83+
private static final String TEXT_LEAF_LC = SvgConstants.Tags.TEXT_LEAF.toLowerCase();
84+
85+
/**
86+
* Creates a new {@link DefaultSvgNodeRendererMapper} instance.
87+
*/
8088
DefaultSvgNodeRendererMapper() {
8189
}
8290

83-
Map<String, Class<? extends ISvgNodeRenderer>> getMapping() {
84-
Map<String, Class<? extends ISvgNodeRenderer>> result = new HashMap<>();
85-
86-
result.put(SvgConstants.Tags.CIRCLE, CircleSvgNodeRenderer.class);
87-
result.put(SvgConstants.Tags.CLIP_PATH, ClipPathSvgNodeRenderer.class);
88-
result.put(SvgConstants.Tags.DEFS, DefsSvgNodeRenderer.class);
89-
result.put(SvgConstants.Tags.ELLIPSE, EllipseSvgNodeRenderer.class);
90-
result.put(SvgConstants.Tags.G, GroupSvgNodeRenderer.class);
91-
result.put(SvgConstants.Tags.IMAGE, ImageSvgNodeRenderer.class);
92-
result.put(SvgConstants.Tags.LINE, LineSvgNodeRenderer.class);
93-
result.put(SvgConstants.Tags.LINEAR_GRADIENT, LinearGradientSvgNodeRenderer.class);
94-
result.put(SvgConstants.Tags.MARKER, MarkerSvgNodeRenderer.class);
95-
result.put(SvgConstants.Tags.PATTERN, PatternSvgNodeRenderer.class);
96-
result.put(SvgConstants.Tags.PATH, PathSvgNodeRenderer.class);
97-
result.put(SvgConstants.Tags.POLYGON, PolygonSvgNodeRenderer.class);
98-
result.put(SvgConstants.Tags.POLYLINE, PolylineSvgNodeRenderer.class);
99-
result.put(SvgConstants.Tags.RECT, RectangleSvgNodeRenderer.class);
100-
result.put(SvgConstants.Tags.STOP, StopSvgNodeRenderer.class);
101-
result.put(SvgConstants.Tags.SVG, SvgTagSvgNodeRenderer.class);
102-
result.put(SvgConstants.Tags.SYMBOL, SymbolSvgNodeRenderer.class);
103-
result.put(SvgConstants.Tags.TEXT, TextSvgBranchRenderer.class);
104-
result.put(SvgConstants.Tags.TSPAN, TextSvgTSpanBranchRenderer.class);
105-
result.put(SvgConstants.Tags.USE, UseSvgNodeRenderer.class);
106-
result.put(SvgConstants.Tags.TEXT_LEAF, TextLeafSvgNodeRenderer.class);
91+
private static final Map<String, ISvgNodeRendererCreator> mapping;
92+
private static final Collection<String> ignored;
93+
94+
static {
95+
Map<String, ISvgNodeRendererCreator> result = new HashMap<>();
96+
result.put(SvgConstants.Tags.CIRCLE, () -> new CircleSvgNodeRenderer());
97+
result.put(SvgConstants.Tags.CLIP_PATH, () -> new ClipPathSvgNodeRenderer());
98+
result.put(SvgConstants.Tags.DEFS, () -> new DefsSvgNodeRenderer());
99+
result.put(SvgConstants.Tags.ELLIPSE, () -> new EllipseSvgNodeRenderer());
100+
result.put(SvgConstants.Tags.G, () -> new GroupSvgNodeRenderer());
101+
result.put(SvgConstants.Tags.IMAGE, () -> new ImageSvgNodeRenderer());
102+
result.put(SvgConstants.Tags.LINE, () -> new LineSvgNodeRenderer());
103+
result.put(SvgConstants.Tags.LINEAR_GRADIENT, () -> new LinearGradientSvgNodeRenderer());
104+
result.put(SvgConstants.Tags.MARKER, () -> new MarkerSvgNodeRenderer());
105+
result.put(SvgConstants.Tags.PATTERN, () -> new PatternSvgNodeRenderer());
106+
result.put(SvgConstants.Tags.PATH, () -> new PathSvgNodeRenderer());
107+
result.put(SvgConstants.Tags.POLYGON, () -> new PolygonSvgNodeRenderer());
108+
result.put(SvgConstants.Tags.POLYLINE, () -> new PolylineSvgNodeRenderer());
109+
result.put(SvgConstants.Tags.RECT, () -> new RectangleSvgNodeRenderer());
110+
result.put(SvgConstants.Tags.STOP, () -> new StopSvgNodeRenderer());
111+
result.put(SvgConstants.Tags.SVG, () -> new SvgTagSvgNodeRenderer());
112+
result.put(SvgConstants.Tags.SYMBOL, () -> new SymbolSvgNodeRenderer());
113+
result.put(SvgConstants.Tags.TEXT, () -> new TextSvgBranchRenderer());
114+
result.put(SvgConstants.Tags.TSPAN, () -> new TextSvgTSpanBranchRenderer());
115+
result.put(SvgConstants.Tags.USE, () -> new UseSvgNodeRenderer());
116+
result.put(SvgConstants.Tags.TEXT_LEAF, () -> new TextLeafSvgNodeRenderer());
107117

108118
// TODO: DEVSIX-3923 remove normalization (.toLowerCase)
109-
result.put(SvgConstants.Tags.CLIP_PATH.toLowerCase(), ClipPathSvgNodeRenderer.class);
110-
result.put(SvgConstants.Tags.LINEAR_GRADIENT.toLowerCase(), LinearGradientSvgNodeRenderer.class);
111-
result.put(SvgConstants.Tags.TEXT_LEAF.toLowerCase(), TextLeafSvgNodeRenderer.class);
119+
result.put(CLIP_PATH_LC, () -> new ClipPathSvgNodeRenderer());
120+
result.put(LINEAR_GRADIENT_LC, () -> new LinearGradientSvgNodeRenderer());
121+
result.put(TEXT_LEAF_LC, () -> new TextLeafSvgNodeRenderer());
112122

113-
return result;
114-
}
115-
116-
Collection<String> getIgnoredTags() {
117-
Collection<String> ignored = new HashSet<>();
123+
mapping = Collections.unmodifiableMap(result);
118124

119125
// Not supported tags as of yet
120-
ignored.add(SvgConstants.Tags.A);
121-
ignored.add(SvgConstants.Tags.ALT_GLYPH);
122-
ignored.add(SvgConstants.Tags.ALT_GLYPH_DEF);
123-
ignored.add(SvgConstants.Tags.ALT_GLYPH_ITEM);
124-
125-
ignored.add(SvgConstants.Tags.COLOR_PROFILE);
126-
127-
ignored.add(SvgConstants.Tags.DESC);
128-
129-
ignored.add(SvgConstants.Tags.FE_BLEND);
130-
ignored.add(SvgConstants.Tags.FE_COLOR_MATRIX);
131-
ignored.add(SvgConstants.Tags.FE_COMPONENT_TRANSFER);
132-
ignored.add(SvgConstants.Tags.FE_COMPOSITE);
133-
ignored.add(SvgConstants.Tags.FE_COMVOLVE_MATRIX);
134-
ignored.add(SvgConstants.Tags.FE_DIFFUSE_LIGHTING);
135-
ignored.add(SvgConstants.Tags.FE_DISPLACEMENT_MAP);
136-
ignored.add(SvgConstants.Tags.FE_DISTANT_LIGHT);
137-
ignored.add(SvgConstants.Tags.FE_FLOOD);
138-
ignored.add(SvgConstants.Tags.FE_FUNC_A);
139-
ignored.add(SvgConstants.Tags.FE_FUNC_B);
140-
ignored.add(SvgConstants.Tags.FE_FUNC_G);
141-
ignored.add(SvgConstants.Tags.FE_FUNC_R);
142-
ignored.add(SvgConstants.Tags.FE_GAUSSIAN_BLUR);
143-
ignored.add(SvgConstants.Tags.FE_IMAGE);
144-
ignored.add(SvgConstants.Tags.FE_MERGE);
145-
ignored.add(SvgConstants.Tags.FE_MERGE_NODE);
146-
ignored.add(SvgConstants.Tags.FE_MORPHOLOGY);
147-
ignored.add(SvgConstants.Tags.FE_OFFSET);
148-
ignored.add(SvgConstants.Tags.FE_POINT_LIGHT);
149-
ignored.add(SvgConstants.Tags.FE_SPECULAR_LIGHTING);
150-
ignored.add(SvgConstants.Tags.FE_SPOTLIGHT);
151-
ignored.add(SvgConstants.Tags.FE_TILE);
152-
ignored.add(SvgConstants.Tags.FE_TURBULENCE);
153-
ignored.add(SvgConstants.Tags.FILTER);
154-
ignored.add(SvgConstants.Tags.FONT);
155-
ignored.add(SvgConstants.Tags.FONT_FACE);
156-
ignored.add(SvgConstants.Tags.FONT_FACE_FORMAT);
157-
ignored.add(SvgConstants.Tags.FONT_FACE_NAME);
158-
ignored.add(SvgConstants.Tags.FONT_FACE_SRC);
159-
ignored.add(SvgConstants.Tags.FONT_FACE_URI);
160-
ignored.add(SvgConstants.Tags.FOREIGN_OBJECT);
161-
162-
ignored.add(SvgConstants.Tags.GLYPH);
163-
ignored.add(SvgConstants.Tags.GLYPH_REF);
164-
165-
ignored.add(SvgConstants.Tags.HKERN);
166-
167-
ignored.add(SvgConstants.Tags.MASK);
168-
ignored.add(SvgConstants.Tags.METADATA);
169-
ignored.add(SvgConstants.Tags.MISSING_GLYPH);
170-
171-
ignored.add(SvgConstants.Tags.RADIAL_GRADIENT);
172-
173-
ignored.add(SvgConstants.Tags.STYLE);
174-
175-
ignored.add(SvgConstants.Tags.TITLE);
126+
Collection<String> ignoredTags = new HashSet<>();
127+
128+
ignoredTags.add(SvgConstants.Tags.A);
129+
ignoredTags.add(SvgConstants.Tags.ALT_GLYPH);
130+
ignoredTags.add(SvgConstants.Tags.ALT_GLYPH_DEF);
131+
ignoredTags.add(SvgConstants.Tags.ALT_GLYPH_ITEM);
132+
133+
ignoredTags.add(SvgConstants.Tags.COLOR_PROFILE);
134+
135+
ignoredTags.add(SvgConstants.Tags.DESC);
136+
137+
ignoredTags.add(SvgConstants.Tags.FE_BLEND);
138+
ignoredTags.add(SvgConstants.Tags.FE_COLOR_MATRIX);
139+
ignoredTags.add(SvgConstants.Tags.FE_COMPONENT_TRANSFER);
140+
ignoredTags.add(SvgConstants.Tags.FE_COMPOSITE);
141+
ignoredTags.add(SvgConstants.Tags.FE_COMVOLVE_MATRIX);
142+
ignoredTags.add(SvgConstants.Tags.FE_DIFFUSE_LIGHTING);
143+
ignoredTags.add(SvgConstants.Tags.FE_DISPLACEMENT_MAP);
144+
ignoredTags.add(SvgConstants.Tags.FE_DISTANT_LIGHT);
145+
ignoredTags.add(SvgConstants.Tags.FE_FLOOD);
146+
ignoredTags.add(SvgConstants.Tags.FE_FUNC_A);
147+
ignoredTags.add(SvgConstants.Tags.FE_FUNC_B);
148+
ignoredTags.add(SvgConstants.Tags.FE_FUNC_G);
149+
ignoredTags.add(SvgConstants.Tags.FE_FUNC_R);
150+
ignoredTags.add(SvgConstants.Tags.FE_GAUSSIAN_BLUR);
151+
ignoredTags.add(SvgConstants.Tags.FE_IMAGE);
152+
ignoredTags.add(SvgConstants.Tags.FE_MERGE);
153+
ignoredTags.add(SvgConstants.Tags.FE_MERGE_NODE);
154+
ignoredTags.add(SvgConstants.Tags.FE_MORPHOLOGY);
155+
ignoredTags.add(SvgConstants.Tags.FE_OFFSET);
156+
ignoredTags.add(SvgConstants.Tags.FE_POINT_LIGHT);
157+
ignoredTags.add(SvgConstants.Tags.FE_SPECULAR_LIGHTING);
158+
ignoredTags.add(SvgConstants.Tags.FE_SPOTLIGHT);
159+
ignoredTags.add(SvgConstants.Tags.FE_TILE);
160+
ignoredTags.add(SvgConstants.Tags.FE_TURBULENCE);
161+
ignoredTags.add(SvgConstants.Tags.FILTER);
162+
ignoredTags.add(SvgConstants.Tags.FONT);
163+
ignoredTags.add(SvgConstants.Tags.FONT_FACE);
164+
ignoredTags.add(SvgConstants.Tags.FONT_FACE_FORMAT);
165+
ignoredTags.add(SvgConstants.Tags.FONT_FACE_NAME);
166+
ignoredTags.add(SvgConstants.Tags.FONT_FACE_SRC);
167+
ignoredTags.add(SvgConstants.Tags.FONT_FACE_URI);
168+
ignoredTags.add(SvgConstants.Tags.FOREIGN_OBJECT);
169+
170+
ignoredTags.add(SvgConstants.Tags.GLYPH);
171+
ignoredTags.add(SvgConstants.Tags.GLYPH_REF);
172+
173+
ignoredTags.add(SvgConstants.Tags.HKERN);
174+
175+
ignoredTags.add(SvgConstants.Tags.MASK);
176+
ignoredTags.add(SvgConstants.Tags.METADATA);
177+
ignoredTags.add(SvgConstants.Tags.MISSING_GLYPH);
178+
179+
ignoredTags.add(SvgConstants.Tags.RADIAL_GRADIENT);
180+
181+
ignoredTags.add(SvgConstants.Tags.STYLE);
182+
183+
ignoredTags.add(SvgConstants.Tags.TITLE);
184+
185+
ignored = Collections.unmodifiableCollection(ignoredTags);
186+
}
176187

188+
/**
189+
* Gets the default SVG tags mapping.
190+
*
191+
* @return the default SVG tags mapping
192+
*/
193+
Map<String, ISvgNodeRendererCreator> getMapping() {
194+
return mapping;
195+
}
196+
197+
/**
198+
* Gets the default ignored SVG tags.
199+
* @return default ignored SVG tags
200+
*/
201+
Collection<String> getIgnoredTags() {
177202
return ignored;
178203
}
204+
205+
/**
206+
* Represents a function, which creates {@link ISvgNodeRenderer} instance.
207+
*/
208+
@FunctionalInterface
209+
public interface ISvgNodeRendererCreator {
210+
/**
211+
* Creates an {@link ISvgNodeRenderer} instance.
212+
* @return {@link ISvgNodeRenderer} instance.
213+
*/
214+
ISvgNodeRenderer create();
215+
}
179216
}

svg/src/test/java/com/itextpdf/svg/renderers/factories/DefaultRendererMapperTest.java

Lines changed: 0 additions & 72 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.itextpdf.svg.renderers.factories;
2+
3+
import com.itextpdf.test.ExtendedITextTest;
4+
import com.itextpdf.test.annotations.type.UnitTest;
5+
6+
import org.junit.Assert;
7+
import org.junit.Test;
8+
import org.junit.experimental.categories.Category;
9+
10+
@Category(UnitTest.class)
11+
public class DefaultSvgNodeRendererMapperTest extends ExtendedITextTest {
12+
13+
private DefaultSvgNodeRendererMapper mapper = new DefaultSvgNodeRendererMapper();
14+
15+
@Test
16+
public void mapperNotEmptyTest() {
17+
boolean result = mapper.getMapping().isEmpty();
18+
Assert.assertFalse(result);
19+
}
20+
21+
@Test
22+
public void ignoredTagsNotEmptyTest() {
23+
boolean result = mapper.getIgnoredTags().isEmpty();
24+
Assert.assertFalse(result);
25+
}
26+
}

0 commit comments

Comments
 (0)