source: josm/trunk/src/com/kitfox/svg/SVGLoader.java@ 11525

Last change on this file since 11525 was 11525, checked in by Don-vip, 7 years ago

see #14319 - update to latest version of svgSalamander (2017-01-07, patched)

  • Property svn:eol-style set to native
File size: 8.9 KB
Line 
1/*
2 * SVG Salamander
3 * Copyright (c) 2004, Mark McKay
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
9 *
10 * - Redistributions of source code must retain the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
32 * projects can be found at http://www.kitfox.com
33 *
34 * Created on February 18, 2004, 5:09 PM
35 */
36
37package com.kitfox.svg;
38
39
40import java.net.URI;
41import java.util.HashMap;
42import java.util.HashSet;
43import java.util.LinkedList;
44import java.util.logging.Level;
45import java.util.logging.Logger;
46
47import org.xml.sax.Attributes;
48import org.xml.sax.SAXException;
49import org.xml.sax.helpers.DefaultHandler;
50
51/**
52 * @author Mark McKay
53 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
54 */
55public class SVGLoader extends DefaultHandler
56{
57 final HashMap<String, Class<?>> nodeClasses = new HashMap<>();
58 //final HashMap attribClasses = new HashMap();
59 final LinkedList<SVGElement> buildStack = new LinkedList<>();
60
61 final HashSet<String> ignoreClasses = new HashSet<>();
62
63 final SVGLoaderHelper helper;
64
65 /**
66 * The diagram that represents the base of this SVG document we're loading.
67 * Will be augmented to include node indexing info and other useful stuff.
68 */
69 final SVGDiagram diagram;
70
71// SVGElement loadRoot;
72
73 //Used to keep track of document elements that are not part of the SVG namespace
74 int skipNonSVGTagDepth = 0;
75 int indent = 0;
76
77 final boolean verbose;
78
79 /** Creates a new instance of SVGLoader */
80 public SVGLoader(URI xmlBase, SVGUniverse universe)
81 {
82 this(xmlBase, universe, false);
83 }
84
85 public SVGLoader(URI xmlBase, SVGUniverse universe, boolean verbose)
86 {
87 this.verbose = verbose;
88
89 diagram = new SVGDiagram(xmlBase, universe);
90
91 //Compile a list of important builder classes
92 nodeClasses.put("a", A.class);
93 nodeClasses.put("circle", Circle.class);
94 nodeClasses.put("clippath", ClipPath.class);
95 nodeClasses.put("defs", Defs.class);
96 nodeClasses.put("desc", Desc.class);
97 nodeClasses.put("ellipse", Ellipse.class);
98 nodeClasses.put("filter", Filter.class);
99 nodeClasses.put("font", Font.class);
100 nodeClasses.put("font-face", FontFace.class);
101 nodeClasses.put("g", Group.class);
102 nodeClasses.put("glyph", Glyph.class);
103 nodeClasses.put("hkern", Hkern.class);
104 nodeClasses.put("image", ImageSVG.class);
105 nodeClasses.put("line", Line.class);
106 nodeClasses.put("lineargradient", LinearGradient.class);
107 nodeClasses.put("marker", Marker.class);
108 nodeClasses.put("metadata", Metadata.class);
109 nodeClasses.put("missing-glyph", MissingGlyph.class);
110 nodeClasses.put("path", Path.class);
111 nodeClasses.put("pattern", PatternSVG.class);
112 nodeClasses.put("polygon", Polygon.class);
113 nodeClasses.put("polyline", Polyline.class);
114 nodeClasses.put("radialgradient", RadialGradient.class);
115 nodeClasses.put("rect", Rect.class);
116 nodeClasses.put("shape", ShapeElement.class);
117 nodeClasses.put("stop", Stop.class);
118 nodeClasses.put("style", Style.class);
119 nodeClasses.put("svg", SVGRoot.class);
120 nodeClasses.put("symbol", Symbol.class);
121 nodeClasses.put("text", Text.class);
122 nodeClasses.put("title", Title.class);
123 nodeClasses.put("tspan", Tspan.class);
124 nodeClasses.put("use", Use.class);
125
126 ignoreClasses.add("midpointstop");
127
128 //attribClasses.put("clip-path", StyleUrl.class);
129 //attribClasses.put("color", StyleColor.class);
130
131 helper = new SVGLoaderHelper(xmlBase, universe, diagram);
132 }
133
134 private String printIndent(int indent, String indentStrn)
135 {
136 StringBuffer sb = new StringBuffer();
137 for (int i = 0; i < indent; i++)
138 {
139 sb.append(indentStrn);
140 }
141 return sb.toString();
142 }
143
144 @Override
145 public void startDocument() throws SAXException
146 {
147// System.err.println("Start doc");
148
149// buildStack.clear();
150 }
151
152 @Override
153 public void endDocument() throws SAXException
154 {
155// System.err.println("End doc");
156 }
157
158 @Override
159 public void startElement(String namespaceURI, String sName, String qName, Attributes attrs) throws SAXException
160 {
161 if (verbose)
162 {
163 System.err.println(printIndent(indent, " ") + "Starting parse of tag " + sName+ ": " + namespaceURI);
164 }
165 indent++;
166
167 if (skipNonSVGTagDepth != 0 || (!namespaceURI.equals("") && !namespaceURI.equals(SVGElement.SVG_NS)))
168 {
169 skipNonSVGTagDepth++;
170 return;
171 }
172
173 sName = sName.toLowerCase();
174
175//javax.swing.JOptionPane.showMessageDialog(null, sName);
176
177 Object obj = nodeClasses.get(sName);
178 if (obj == null)
179 {
180 if (!ignoreClasses.contains(sName))
181 {
182 if (verbose)
183 {
184 System.err.println("SVGLoader: Could not identify tag '" + sName + "'");
185 }
186 }
187 return;
188 }
189
190//Debug info tag depth
191//for (int i = 0; i < buildStack.size(); i++) System.err.print(" ");
192//System.err.println("+" + sName);
193
194 try {
195 Class<?> cls = (Class<?>)obj;
196 SVGElement svgEle = (SVGElement)cls.newInstance();
197
198 SVGElement parent = null;
199 if (buildStack.size() != 0) parent = buildStack.getLast();
200 svgEle.loaderStartElement(helper, attrs, parent);
201
202 buildStack.addLast(svgEle);
203 }
204 catch (Exception e)
205 {
206 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
207 "Could not load", e);
208 throw new SAXException(e);
209 }
210
211 }
212
213 @Override
214 public void endElement(String namespaceURI, String sName, String qName)
215 throws SAXException
216 {
217 indent--;
218 if (verbose)
219 {
220 System.err.println(printIndent(indent, " ") + "Ending parse of tag " + sName+ ": " + namespaceURI);
221 }
222
223 if (skipNonSVGTagDepth != 0)
224 {
225 skipNonSVGTagDepth--;
226 return;
227 }
228
229 sName = sName.toLowerCase();
230
231 Object obj = nodeClasses.get(sName);
232 if (obj == null) return;
233
234//Debug info tag depth
235//for (int i = 0; i < buildStack.size(); i++) System.err.print(" ");
236//System.err.println("-" + sName);
237
238 try {
239 SVGElement svgEle = buildStack.removeLast();
240
241 svgEle.loaderEndElement(helper);
242
243 SVGElement parent = null;
244 if (buildStack.size() != 0)
245 {
246 parent = buildStack.getLast();
247 }
248 //else loadRoot = (SVGElement)svgEle;
249
250 if (parent != null)
251 {
252 parent.loaderAddChild(helper, svgEle);
253 }
254 else
255 {
256 diagram.setRoot((SVGRoot)svgEle);
257 }
258
259 }
260 catch (Exception e)
261 {
262 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
263 "Could not parse", e);
264 throw new SAXException(e);
265 }
266 }
267
268 @Override
269 public void characters(char buf[], int offset, int len)
270 throws SAXException
271 {
272 if (skipNonSVGTagDepth != 0)
273 {
274 return;
275 }
276
277 if (buildStack.size() != 0)
278 {
279 SVGElement parent = buildStack.getLast();
280 String s = new String(buf, offset, len);
281 parent.loaderAddText(helper, s);
282 }
283 }
284
285 @Override
286 public void processingInstruction(String target, String data)
287 throws SAXException
288 {
289 //Check for external style sheet
290 }
291
292// public SVGElement getLoadRoot() { return loadRoot; }
293 public SVGDiagram getLoadedDiagram() { return diagram; }
294}
Note: See TracBrowser for help on using the repository browser.