1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.svg;
16
17 import java.util.HashMap;
18 import java.util.LinkedHashMap;
19 import java.util.Map;
20
21 import org.htmlunit.SgmlPage;
22 import org.htmlunit.html.DomAttr;
23 import org.htmlunit.html.DomElement;
24 import org.htmlunit.html.ElementFactory;
25 import org.htmlunit.util.StringUtils;
26 import org.xml.sax.Attributes;
27
28
29
30
31
32
33
34
35
36 public class SvgElementFactory implements ElementFactory {
37
38 private static final Class<?>[] CLASSES_ = {SvgAltGlyph.class, SvgAltGlyphDef.class, SvgAltGlyphItem.class,
39 SvgAnchor.class, SvgAnimate.class, SvgAnimateColor.class, SvgAnimateMotion.class, SvgAnimateTransform.class,
40 SvgCircle.class, SvgClipPath.class, SvgColorProfile.class, SvgCursor.class, SvgDefs.class, SvgDesc.class,
41 SvgEllipse.class, SvgFeBlend.class, SvgFeColorMatrix.class, SvgFeComponentTransfer.class,
42 SvgFeComposite.class, SvgFeConvolveMatrix.class, SvgFeDiffuseLighting.class, SvgFeDisplacementMap.class,
43 SvgFeDistantLight.class, SvgFeFlood.class, SvgFeFuncA.class, SvgFeFuncB.class, SvgFeFuncG.class,
44 SvgFeFuncR.class, SvgFeGaussianBlur.class, SvgFeImage.class, SvgFeMerge.class, SvgFeMergeNode.class,
45 SvgFeMorphology.class, SvgFeOffset.class, SvgFePointLight.class, SvgFeSpecularLighting.class,
46 SvgFeSpotLight.class, SvgFeTile.class, SvgFeTurbulence.class, SvgFilter.class, SvgFont.class,
47 SvgFontFace.class, SvgFontFaceFormat.class, SvgFontFaceName.class, SvgFontFaceSrc.class,
48 SvgFontFaceURI.class, SvgForeignObject.class, SvgGlyph.class, SvgGlyphRef.class, SvgGroup.class,
49 SvgHKern.class, SvgImage.class, SvgLine.class, SvgLinearGradient.class, SvgMarker.class, SvgMask.class,
50 SvgMetadata.class, SvgMissingGlyph.class, SvgMPath.class, SvgPath.class, SvgPattern.class, SvgPolygon.class,
51 SvgPolyline.class, SvgRadialGradient.class, SvgRect.class, SvgScript.class, SvgSet.class, SvgStop.class,
52 SvgStyle.class, SvgSwitch.class, SvgSymbol.class, SvgText.class, SvgTextPath.class,
53 SvgTitle.class, SvgTRef.class, SvgTSpan.class, SvgUse.class, SvgView.class, SvgVKern.class
54 };
55
56 private static final Map<String, Class<?>> ELEMENTS_ = new HashMap<>();
57
58 static {
59 try {
60 for (final Class<?> klass : CLASSES_) {
61 final String key = klass.getField("TAG_NAME").get(null).toString();
62 ELEMENTS_.put(StringUtils.toRootLowerCase(key), klass);
63 }
64 }
65 catch (final Exception e) {
66 throw new IllegalStateException(e);
67 }
68 }
69
70
71
72
73 @Override
74 public DomElement createElement(final SgmlPage page, final String tagName, final Attributes attributes) {
75 throw new IllegalStateException("SVG.createElement not yet implemented!");
76 }
77
78
79
80
81 @Override
82 public DomElement createElementNS(final SgmlPage page, final String namespaceURI, String qualifiedNameLC,
83 final Attributes attributes) {
84
85 final Map<String, DomAttr> attributeMap = toMap(page, attributes);
86 qualifiedNameLC = StringUtils.toRootLowerCase(qualifiedNameLC);
87 String tagNameLC = qualifiedNameLC;
88 if (tagNameLC.indexOf(':') != -1) {
89 tagNameLC = tagNameLC.substring(tagNameLC.indexOf(':') + 1);
90 }
91 DomElement element = null;
92
93 final Class<?> klass = ELEMENTS_.get(tagNameLC);
94 if (klass != null) {
95 try {
96 element = (DomElement) klass.getDeclaredConstructors()[0]
97 .newInstance(namespaceURI, qualifiedNameLC, page, attributeMap);
98 }
99 catch (final Exception e) {
100 throw new IllegalStateException(e);
101 }
102 }
103 if (element == null) {
104 element = new SvgElement(namespaceURI, qualifiedNameLC, page, attributeMap);
105 }
106 return element;
107 }
108
109 private static Map<String, DomAttr> toMap(final SgmlPage page, final Attributes attributes) {
110 Map<String, DomAttr> attributeMap = null;
111 if (attributes != null) {
112 attributeMap = new LinkedHashMap<>(attributes.getLength());
113 for (int i = 0; i < attributes.getLength(); i++) {
114 final String qName = attributes.getQName(i);
115
116 if (!attributeMap.containsKey(qName)) {
117 String namespaceURI = attributes.getURI(i);
118 if (namespaceURI != null && namespaceURI.isEmpty()) {
119 namespaceURI = null;
120 }
121 final DomAttr newAttr = new DomAttr(page, namespaceURI, qName, attributes.getValue(i), true);
122 attributeMap.put(qName, newAttr);
123 }
124 }
125 }
126 return attributeMap;
127 }
128
129
130
131
132
133
134 public boolean isSupported(final String tagNameLowerCase) {
135 return ELEMENTS_.containsKey(tagNameLowerCase);
136 }
137 }