1
22 package org.crosswire.jsword.book.filter.thml;
23
24 import java.util.HashMap;
25 import java.util.LinkedList;
26 import java.util.Locale;
27 import java.util.Map;
28
29 import org.crosswire.jsword.book.Book;
30 import org.crosswire.jsword.book.DataPolice;
31 import org.crosswire.jsword.passage.Key;
32 import org.jdom.Content;
33 import org.jdom.Element;
34 import org.jdom.Text;
35 import org.xml.sax.Attributes;
36 import org.xml.sax.SAXException;
37 import org.xml.sax.helpers.DefaultHandler;
38
39
51 public class CustomHandler extends DefaultHandler {
52
55 public CustomHandler(Book book, Key key) {
56 this.book = book;
57 this.key = key;
58 this.stack = new LinkedList<Content>();
59 }
60
61 @Override
62 public void startElement(String uri, String localname, String qname, Attributes attrs) throws SAXException {
63 Element ele = null;
64
65 if (!stack.isEmpty()) {
68 Object top = stack.getFirst();
69
70 if (top == null) {
73 return;
74 }
75
76 if (top instanceof Element) {
78 ele = (Element) top;
79 }
80 }
81
82 Tag t = getTag(localname, qname);
83
84 if (t != null) {
85 stack.addFirst(t.processTag(book, key, ele, attrs));
86 }
87 }
88
89 @Override
90 public void characters(char[] data, int offset, int length) {
91 String text = new String(data, offset, length);
93
94 if (stack.isEmpty()) {
95 stack.addFirst(new Text(text));
96 return;
97 }
98
99 Content top = stack.getFirst();
101
102 if (top == null) {
105 return;
106 }
107
108 if (top instanceof Text) {
109 ((Text) top).append(text);
110 return;
111 }
112
113 if (top instanceof Element) {
114 Element current = (Element) top;
115
116 int size = current.getContentSize();
117
118 if (size > 0) {
124 Content last = current.getContent(size - 1);
125 if (last instanceof Text) {
126 ((Text) last).append(text);
127 return;
128 }
129 }
130 current.addContent(new Text(text));
131 }
132 }
133
134 @Override
135 public void endElement(String uri, String localname, String qname) {
136 if (stack.isEmpty()) {
137 return;
138 }
139 Content top = stack.removeFirst();
142 if (top instanceof Element) {
143 Element finished = (Element) top;
144 Tag t = getTag(localname, qname);
145
146 if (t != null) {
147 t.processContent(book, key, finished);
148 }
149
150 if (stack.isEmpty()) {
153 rootElement = finished;
154 }
155 }
156 }
157
158 public Element getRootElement() {
159 return rootElement;
160 }
161
162 private Tag getTag(String localname, String qname) {
163 Tag t = TAG_MAP.get(qname);
164
165 if (t == null) {
169 t = TAG_MAP.get(qname.toLowerCase(Locale.ENGLISH));
170
171 if (t == null) {
172 DataPolice.report(book, key, "Unknown thml element: " + localname + " qname=" + qname);
173
174 t = new AnonymousTag(qname);
176 TAG_MAP.put(qname, t);
177 return t;
178 }
179
180 DataPolice.report(book, key, "Wrong case used in thml element: " + qname);
181 }
182 return t;
183 }
184
185
189 private Element rootElement;
190
191
194 private Book book;
195
196
199 private Key key;
200
201
204 private LinkedList<Content> stack;
205
206
209 private static final Map<String, Tag> TAG_MAP = new HashMap<String, Tag>();
210
211 static {
212
216 Tag[] tags = new Tag[] {
217 new ATag(), new AbbrTag(), new AliasTag("acronym", new AbbrTag()),
219 new AnonymousTag("address"),
220 new SkipTag("applet"),
221 new SkipTag("area"),
222 new BTag(), new SkipTag("base"),
223 new SkipTag("basefont"),
224 new IgnoreTag("bdo"),
225 new BigTag(), new BlockquoteTag(), new IgnoreTag("body"),
226 new BrTag(), new SkipTag("button"),
227 new AnonymousTag("caption"),
228 new CenterTag(), new AnonymousTag("cite"),
229 new AnonymousTag("code"),
230 new SkipTag("col"),
231 new SkipTag("colgroup"),
232 new AliasTag("dd", new LiTag()),
233 new AnonymousTag("del"),
234 new AnonymousTag("dfn"),
235 new DivTag(), new AliasTag("dl", new UlTag()),
236 new AliasTag("dt", new LiTag()),
237 new AliasTag("em", new ITag()),
238 new IgnoreTag("fieldset"),
239 new FontTag(), new SkipTag("form"),
240 new SkipTag("frame"),
241 new SkipTag("frameset"),
242 new AliasTag("h1", new HTag(1)),
243 new AliasTag("h2", new HTag(2)),
244 new AliasTag("h3", new HTag(3)),
245 new AliasTag("h4", new HTag(4)),
246 new AliasTag("h5", new HTag(5)),
247 new AliasTag("h6", new HTag(6)),
248 new SkipTag("head"),
249 new HrTag(), new IgnoreTag("html"),
250 new IgnoreTag("frameset"),
251 new ITag(), new SkipTag("iframe"),
252 new ImgTag(), new SkipTag("input"),
253 new AnonymousTag("ins"),
254 new AnonymousTag("kbd"),
255 new AnonymousTag("label"),
256 new AnonymousTag("legend"),
257 new LiTag(), new SkipTag("link"),
258 new SkipTag("map"),
259 new SkipTag("meta"),
260 new SkipTag("noscript"),
261 new SkipTag("object"),
262 new OlTag(), new SkipTag("optgroup"),
263 new SkipTag("option"),
264 new PTag(), new SkipTag("param"),
265 new IgnoreTag("pre"),
266 new QTag(), new RootTag(), new STag(), new AnonymousTag("samp"),
267 new SkipTag("script"),
268 new SkipTag("select"),
269 new SmallTag(), new IgnoreTag("span"),
270 new AliasTag("strong", new BTag()),
271 new SkipTag("style"),
272 new SubTag(), new SupTag(), new SyncTag(), new TableTag(), new IgnoreTag("tbody"),
273 new TdTag(), new IgnoreTag("tfoot"),
274 new SkipTag("textarea"),
275 new SkipTag("title"),
276 new IgnoreTag("thead"),
277 new ThTag(), new TrTag(), new TtTag(), new UTag(), new UlTag(), new AnonymousTag("var"),
278
279 new AnonymousTag("added"),
283 new AnonymousTag("attr"),
284 new AnonymousTag("argument"),
285 new CitationTag(), new AnonymousTag("date"),
286 new AnonymousTag("deleted"),
287 new AnonymousTag("def"),
288 new AliasTag("div1", new DivTag(1)),
289 new AliasTag("div2", new DivTag(2)),
290 new AliasTag("div3", new DivTag(3)),
291 new AliasTag("div4", new DivTag(4)),
292 new AliasTag("div5", new DivTag(5)),
293 new AliasTag("div6", new DivTag(6)),
294 new ForeignTag(), new AnonymousTag("index"),
295 new AnonymousTag("insertIndex"),
296 new AnonymousTag("glossary"),
297 new NoteTag(), new NameTag(), new PbTag(), new AnonymousTag("scripCom"),
298 new AnonymousTag("scripContext"),
299 new ScripRefTag(), new ScriptureTag(), new TermTag(), new AnonymousTag("unclear"),
300 new VerseTag(),
301 };
302 for (int i = 0; i < tags.length; i++) {
303 Tag t = tags[i];
304 String tagName = t.getTagName();
305 TAG_MAP.put(tagName, t);
306 }
307 }
308
309 }
310