1
22 package org.crosswire.jsword.book;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.Stack;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
34
35 import org.crosswire.common.diff.Difference;
36 import org.crosswire.common.diff.EditType;
37 import org.crosswire.common.util.Logger;
38 import org.crosswire.jsword.passage.Key;
39 import org.crosswire.jsword.passage.KeyFactory;
40 import org.crosswire.jsword.passage.NoSuchKeyException;
41 import org.crosswire.jsword.passage.NoSuchVerseException;
42 import org.crosswire.jsword.passage.PassageKeyFactory;
43 import org.crosswire.jsword.passage.Verse;
44 import org.crosswire.jsword.passage.VerseFactory;
45 import org.jdom.Content;
46 import org.jdom.Element;
47 import org.jdom.Parent;
48 import org.jdom.Text;
49
50
57 public final class OSISUtil
58 {
59
62
65 public static final String HI_ACROSTIC = "acrostic";
67
70 public static final String HI_BOLD = "bold";
72
75 public static final String HI_EMPHASIS = "emphasis";
77
80 public static final String HI_ILLUMINATED = "illuminated";
82
85 public static final String HI_ITALIC = "italic";
87
90 public static final String HI_LINETHROUGH = "line-through";
92
95 public static final String HI_NORMAL = "normal";
97
100 public static final String HI_SMALL_CAPS = "small-caps";
102
105 public static final String HI_SUB = "sub";
107
110 public static final String HI_SUPER = "super";
112
115 public static final String HI_UNDERLINE = "underline";
117
120 public static final String HI_X_CAPS = "x-caps";
122
125 public static final String HI_X_BIG = "x-big";
127
130 public static final String HI_X_SMALL = "x-small";
132
135 public static final String HI_X_TT = "x-tt";
137
140 public static final String SEG_JUSTIFYRIGHT = "text-align: right;";
142
145 public static final String SEG_CENTER = "text-align: center;";
147
150 public static final String DIV_PRE = "x-pre";
152
155 public static final String SEG_COLORPREFIX = "color: ";
157
160 public static final String SEG_SIZEPREFIX = "font-size: ";
162
165 public static final String TYPE_X_PREFIX = "x-";
167
170 public static final String NOTETYPE_STUDY = "x-StudyNote";
172
175 public static final String NOTETYPE_REFERENCE = "crossReference";
177
180 public static final String VARIANT_TYPE = "x-variant"; public static final String VARIANT_CLASS = "x-class";
183
186 public static final String GENERATED_CONTENT = "x-gen";
188
191 public static final String POS_TYPE = "x-pos";
193
196 public static final String DEF_TYPE = "x-def";
198
201 public static final String LEMMA_STRONGS = "strong:"; public static final String MORPH_ROBINSONS = "robinson:";
204
207 public static final String MORPH_STRONGS = "x-StrongsMorph:T";
209
212 public static final String Q_BLOCK = "blockquote";
214
217 public static final String Q_CITATION = "citation";
219
222 public static final String Q_EMBEDDED = "embedded";
224
227 public static final String LIST_ORDERED = "x-ordered"; public static final String LIST_UNORDERED = "x-unordered";
230
233 public static final String TABLE_ROLE_LABEL = "label";
235
238 public static final String CELL_ALIGN_LEFT = "left"; public static final String CELL_ALIGN_RIGHT = "right"; public static final String CELL_ALIGN_CENTER = "center"; public static final String CELL_ALIGN_JUSTIFY = "justify"; public static final String CELL_ALIGN_START = "start"; public static final String CELL_ALIGN_END = "end";
245 public static final String OSIS_ELEMENT_TITLE = "title"; public static final String OSIS_ELEMENT_TABLE = "table"; public static final String OSIS_ELEMENT_SPEECH = "speech"; public static final String OSIS_ELEMENT_SPEAKER = "speaker"; public static final String OSIS_ELEMENT_ROW = "row"; public static final String OSIS_ELEMENT_REFERENCE = "reference"; public static final String OSIS_ELEMENT_NOTE = "note"; public static final String OSIS_ELEMENT_NAME = "name"; public static final String OSIS_ELEMENT_Q = "q"; public static final String OSIS_ELEMENT_LIST = "list"; public static final String OSIS_ELEMENT_P = "p"; public static final String OSIS_ELEMENT_ITEM = "item"; public static final String OSIS_ELEMENT_FIGURE = "figure"; public static final String OSIS_ELEMENT_FOREIGN = "foreign"; public static final String OSIS_ELEMENT_W = "w"; public static final String OSIS_ELEMENT_CHAPTER = "chapter"; public static final String OSIS_ELEMENT_VERSE = "verse"; public static final String OSIS_ELEMENT_CELL = "cell"; public static final String OSIS_ELEMENT_DIV = "div"; public static final String OSIS_ELEMENT_OSIS = "osis"; public static final String OSIS_ELEMENT_WORK = "work"; public static final String OSIS_ELEMENT_HEADER = "header"; public static final String OSIS_ELEMENT_OSISTEXT = "osisText"; public static final String OSIS_ELEMENT_SEG = "seg"; public static final String OSIS_ELEMENT_LG = "lg"; public static final String OSIS_ELEMENT_L = "l"; public static final String OSIS_ELEMENT_LB = "lb"; public static final String OSIS_ELEMENT_HI = "hi";
274 public static final String ATTRIBUTE_TEXT_OSISIDWORK = "osisIDWork"; public static final String ATTRIBUTE_WORK_OSISWORK = "osisWork"; public static final String OSIS_ATTR_OSISID = "osisID"; public static final String OSIS_ATTR_SID = "sID"; public static final String OSIS_ATTR_EID = "eID"; public static final String ATTRIBUTE_W_LEMMA = "lemma"; public static final String ATTRIBUTE_FIGURE_SRC = "src"; public static final String ATTRIBUTE_TABLE_ROLE = "role"; public static final String ATTRIBUTE_CELL_ALIGN = "align"; public static final String OSIS_ATTR_TYPE = "type"; public static final String OSIS_ATTR_CANONICAL = "canonical"; public static final String OSIS_ATTR_SUBTYPE = "subType"; public static final String OSIS_ATTR_REF = "osisRef"; public static final String OSIS_ATTR_LEVEL = "level"; public static final String ATTRIBUTE_SPEAKER_WHO = "who"; public static final String ATTRIBUTE_W_MORPH = "morph"; public static final String ATTRIBUTE_OSISTEXT_OSISIDWORK = "osisIDWork"; public static final String OSIS_ATTR_LANG = "lang"; public static final String ATTRIBUTE_DIV_BOOK = "book";
296
299 private static final String OSISID_PREFIX_BIBLE = "Bible.";
301 private static final Set EXTRA_BIBLICAL_ELEMENTS = new HashSet(Arrays.asList(new String[]
302 {
303 OSIS_ELEMENT_NOTE, OSIS_ELEMENT_TITLE, OSIS_ELEMENT_REFERENCE
304 }));
305
306
309 private static final Logger log = Logger.getLogger(OSISUtil.class);
310
311
314 private OSISUtil()
315 {
316 }
317
318 private static OSISFactory factory = new OSISFactory();
319
320
323 public static OSISFactory factory()
324 {
325 return factory;
326 }
327
328
331 public static class OSISFactory
332 {
333
336 public Element createSeg()
337 {
338 return new Element(OSIS_ELEMENT_SEG);
339 }
340
341
344 public Element createOsisText()
345 {
346 return new Element(OSIS_ELEMENT_OSISTEXT);
347 }
348
349
352 public Element createHeader()
353 {
354 return new Element(OSIS_ELEMENT_HEADER);
355 }
356
357
360 public Element createWork()
361 {
362 return new Element(OSIS_ELEMENT_WORK);
363 }
364
365
368 public Element createOsis()
369 {
370 return new Element(OSIS_ELEMENT_OSIS);
371 }
372
373
376 public Element createDiv()
377 {
378 return new Element(OSIS_ELEMENT_DIV);
379 }
380
381
384 public Element createCell()
385 {
386 return new Element(OSIS_ELEMENT_CELL);
387 }
388
389
392 public Element createHeaderCell()
393 {
394 Element ele = new Element(OSIS_ELEMENT_CELL);
395 ele.setAttribute(ATTRIBUTE_TABLE_ROLE, TABLE_ROLE_LABEL);
396 ele.setAttribute(ATTRIBUTE_CELL_ALIGN, CELL_ALIGN_CENTER);
397 return ele;
398 }
399
400
403 public Element createVerse()
404 {
405 return new Element(OSIS_ELEMENT_VERSE);
406 }
407
408
411 public Element createW()
412 {
413 return new Element(OSIS_ELEMENT_W);
414 }
415
416
419 public Element createFigure()
420 {
421 return new Element(OSIS_ELEMENT_FIGURE);
422 }
423
424
427 public Element createForeign()
428 {
429 return new Element(OSIS_ELEMENT_FOREIGN);
430 }
431
432
435 public Element createItem()
436 {
437 return new Element(OSIS_ELEMENT_ITEM);
438 }
439
440
443 public Element createP()
444 {
445 return new Element(OSIS_ELEMENT_P);
446 }
447
448
451 public Element createList()
452 {
453 return new Element(OSIS_ELEMENT_LIST);
454 }
455
456
459 public Element createQ()
460 {
461 return new Element(OSIS_ELEMENT_Q);
462 }
463
464
467 public Element createName()
468 {
469 return new Element(OSIS_ELEMENT_NAME);
470 }
471
472
475 public Element createNote()
476 {
477 return new Element(OSIS_ELEMENT_NOTE);
478 }
479
480
483 public Element createReference()
484 {
485 return new Element(OSIS_ELEMENT_REFERENCE);
486 }
487
488
491 public Element createRow()
492 {
493 return new Element(OSIS_ELEMENT_ROW);
494 }
495
496
499 public Element createSpeaker()
500 {
501 return new Element(OSIS_ELEMENT_SPEAKER);
502 }
503
504
507 public Element createSpeech()
508 {
509 return new Element(OSIS_ELEMENT_SPEECH);
510 }
511
512
515 public Element createTable()
516 {
517 return new Element(OSIS_ELEMENT_TABLE);
518 }
519
520
523 public Element createTitle()
524 {
525 return new Element(OSIS_ELEMENT_TITLE);
526 }
527
530 public Element createLG()
531 {
532 return new Element(OSIS_ELEMENT_LG);
533 }
534
537 public Element createL()
538 {
539 return new Element(OSIS_ELEMENT_L);
540 }
541
544 public Element createLB()
545 {
546 return new Element(OSIS_ELEMENT_LB);
547 }
548
551 public Element createHI()
552 {
553 return new Element(OSIS_ELEMENT_HI);
554 }
555
556
559 public Text createText(String text)
560 {
561 return new Text(text);
562 }
563 }
564
565
570 public static List getFragment(Element root)
571 {
572 Element content = root;
573 if (OSISUtil.OSIS_ELEMENT_OSIS.equals(root.getName()))
574 {
575 content = root.getChild(OSISUtil.OSIS_ELEMENT_OSISTEXT);
576 }
577
578 if (OSISUtil.OSIS_ELEMENT_OSISTEXT.equals(root.getName()))
579 {
580 content = root.getChild(OSISUtil.OSIS_ELEMENT_DIV);
581 }
582
583 while (content != null && content.getContentSize() == 1)
587 {
588 Content firstChild = content.getContent(0);
589 if (firstChild instanceof Element && OSISUtil.OSIS_ELEMENT_DIV.equals(((Element) firstChild).getName()))
590 {
591 content = (Element) firstChild;
592 }
593 break;
594 }
595
596 assert content != null;
597 return content.getContent();
598 }
599
600
636 public static String getCanonicalText(Element root)
637 {
638 StringBuffer buffer = new StringBuffer();
639
640 List frag = OSISUtil.getFragment(root);
642
643 Iterator dit = frag.iterator();
644 String sID = null;
645 Object data = null;
646 Element ele = null;
647 while (dit.hasNext())
648 {
649 data = dit.next();
650 if (data instanceof Element)
651 {
652 ele = (Element) data;
653 if (!isCanonical(ele))
654 {
655 continue;
656 }
657
658 if (ele.getName().equals(OSISUtil.OSIS_ELEMENT_VERSE))
659 {
660 sID = ele.getAttributeValue(OSISUtil.OSIS_ATTR_SID);
661 }
662
663 if (sID != null)
664 {
665 getCanonicalContent(ele, sID, dit, buffer);
666 }
667 else
668 {
669 getCanonicalContent(ele, null, ele.getContent().iterator(), buffer);
670 }
671 }
672 else if (data instanceof Text)
673 {
674 int lastIndex = buffer.length() - 1;
677 String text = ((Text) data).getText();
678 if (lastIndex >= 0 && !Character.isWhitespace(buffer.charAt(lastIndex)) && !Character.isWhitespace(text.charAt(0)))
679 {
680 buffer.append(' ');
681 }
682 buffer.append(text);
683 }
684 }
685
686 return buffer.toString().trim();
687 }
688
689
694 public static String getPlainText(Element root)
695 {
696 return getTextContent(OSISUtil.getFragment(root));
698 }
699
700
704 public static String getStrongsNumbers(Element root)
705 {
706 StringBuffer buffer = new StringBuffer();
707
708 Iterator contentIter = getDeepContent(root, OSISUtil.OSIS_ELEMENT_W).iterator();
709 while (contentIter.hasNext())
710 {
711 Element ele = (Element) contentIter.next();
712 String attr = ele.getAttributeValue(OSISUtil.ATTRIBUTE_W_LEMMA);
713 if (attr != null)
714 {
715 Matcher matcher = strongsNumberPattern.matcher(attr);
716 while (matcher.find())
717 {
718 String strongsNum = matcher.group(1);
719 if (buffer.length() > 0)
720 {
721 buffer.append(' ');
722 }
723 buffer.append(strongsNum);
724 }
725 }
726 }
727
728 return buffer.toString().trim();
729 }
730
731
735 public static String getReferences(Element root)
736 {
737 KeyFactory keyf = PassageKeyFactory.instance();
738 Key collector = keyf.createEmptyKeyList();
739
740 Iterator contentIter = getDeepContent(root, OSISUtil.OSIS_ELEMENT_REFERENCE).iterator();
741 while (contentIter.hasNext())
742 {
743 Element ele = (Element) contentIter.next();
744 String attr = ele.getAttributeValue(OSISUtil.OSIS_ATTR_REF);
745 if (attr != null)
746 {
747 try
748 {
749 Key key = keyf.getKey(attr);
750 collector.addAll(key);
751 }
752 catch (NoSuchKeyException e)
753 {
754 log.warn("Unable to parse: " + attr, e); }
756 }
757 }
758
759 return collector.getOsisID();
760 }
761
762
767 public static String getNotes(Element root)
768 {
769 StringBuffer buffer = new StringBuffer();
770
771 Iterator contentIter = getDeepContent(root, OSISUtil.OSIS_ELEMENT_NOTE).iterator();
772 while (contentIter.hasNext())
773 {
774 Element ele = (Element) contentIter.next();
775 String attr = ele.getAttributeValue(OSISUtil.OSIS_ATTR_TYPE);
776 if (attr == null || !attr.equals(NOTETYPE_REFERENCE))
777 {
778 if (buffer.length() > 0)
779 {
780 buffer.append(' ');
781 }
782 buffer.append(OSISUtil.getTextContent(ele.getContent()));
783 }
784 }
785
786 return buffer.toString();
787 }
788
789
794 public static String getHeadings(Element root)
795 {
796 StringBuffer buffer = new StringBuffer();
797
798 Iterator contentIter = getDeepContent(root, OSISUtil.OSIS_ELEMENT_TITLE).iterator();
799 while (contentIter.hasNext())
800 {
801 Element ele = (Element) contentIter.next();
802 getCanonicalContent(ele, null, ele.getContent().iterator(), buffer);
803 }
804
805 return buffer.toString();
806 }
807
808 private static void getCanonicalContent(Element parent, String sID, Iterator iter, StringBuffer buffer)
809 {
810 if (!isCanonical(parent))
811 {
812 return;
813 }
814
815 Object data = null;
816 Element ele = null;
817 String eleName = null;
818 String eID = null;
819 while (iter.hasNext())
820 {
821 data = iter.next();
822 if (data instanceof Element)
823 {
824 ele = (Element) data;
825 eleName = ele.getName();
828 eID = ele.getAttributeValue(OSISUtil.OSIS_ATTR_SID);
829 if (eID != null && eID.equals(sID) && eleName.equals(parent.getName()))
830 {
831 break;
832 }
833 OSISUtil.getCanonicalContent(ele, sID, ele.getContent().iterator(), buffer);
834 }
835 else if (data instanceof Text)
836 {
837 int lastIndex = buffer.length() - 1;
840 String text = ((Text) data).getText();
841 if (lastIndex >= 0 && !Character.isWhitespace(buffer.charAt(lastIndex)) && !Character.isWhitespace(text.charAt(0)))
842 {
843 buffer.append(' ');
844 }
845 buffer.append(text);
846 }
847 }
848 }
849
850 private static boolean isCanonical(Content content)
851 {
852 boolean result = true;
853 if (content instanceof Element)
854 {
855 Element element = (Element) content;
856
857 if (EXTRA_BIBLICAL_ELEMENTS.contains(element.getName()))
859 {
860 String canonical = element.getAttributeValue(OSISUtil.OSIS_ATTR_CANONICAL);
861 result = Boolean.valueOf(canonical).booleanValue();
862 }
863 }
864
865 return result;
866 }
867
868 private static String getTextContent(List fragment)
869 {
870 StringBuffer buffer = new StringBuffer();
871
872 Iterator contentIter = fragment.iterator();
873 while (contentIter.hasNext())
874 {
875 Content next = (Content) contentIter.next();
876 recurseElement(next, buffer);
877 }
878
879 return buffer.toString();
880 }
881
882
886 public static Collection getDeepContent(Element div, String name)
887 {
888 List reply = new ArrayList();
889 recurseDeepContent(div, name, reply);
890 return reply;
891 }
892
893
898 public static Verse getVerse(Element ele) throws BookException
899 {
900 if (ele.getName().equals(OSIS_ELEMENT_VERSE))
901 {
902 String osisid = ele.getAttributeValue(OSIS_ATTR_OSISID);
904
905 try
906 {
907 return VerseFactory.fromString(osisid);
908 }
909 catch (NoSuchVerseException ex)
910 {
911 throw new BookException(Msg.OSIS_BADID, ex, new Object[] { osisid });
912 }
913 }
914
915 Parent parent = ele.getParent();
917 if (parent instanceof Element)
918 {
919 return getVerse((Element) parent);
920 }
921
922 throw new BookException(Msg.MISSING_VERSE);
923 }
924
925
929 public static Element createOsisFramework(BookMetaData bmd)
930 {
931 Element osis = factory().createOsis();
932 String osisid = bmd.getInitials();
933
934 Element work = factory().createWork();
935 work.setAttribute(ATTRIBUTE_WORK_OSISWORK, osisid);
936
937 Element header = factory().createHeader();
938 header.addContent(work);
939
940 Element text = factory().createOsisText();
941 text.setAttribute(ATTRIBUTE_TEXT_OSISIDWORK, OSISID_PREFIX_BIBLE + osisid);
942 text.addContent(header);
943
944 osis.addContent(text);
945
946 return osis;
947 }
948
949
954 public static List diffToOsis(List diffs)
955 {
956 Element div = factory().createDiv();
957
958 for (int x = 0; x < diffs.size(); x++)
959 {
960 Difference diff = (Difference) diffs.get(x);
961 EditType editType = diff.getEditType(); Text text = factory.createText(diff.getText());
964 if (EditType.DELETE.equals(editType))
965 {
966 Element hi = factory().createHI();
967 hi.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.HI_LINETHROUGH);
968 hi.addContent(text);
969 div.addContent(hi);
970 }
971 else if (EditType.INSERT.equals(editType))
972 {
973 Element hi = factory().createHI();
974 hi.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.HI_UNDERLINE);
975 hi.addContent(text);
976 div.addContent(hi);
977 }
978 else
979 {
980 div.addContent(text);
981 }
982 }
983 return div.cloneContent();
984 }
985
986 public static List rtfToOsis(String rtf)
987 {
988 Element div = factory().createDiv();
989 Stack stack = new Stack();
990 stack.push(div);
991
992 int strlen = rtf.length();
993
994 StringBuffer text = new StringBuffer(strlen);
995
996 int i = 0;
997 for (i = 0; i < strlen; i++)
998 {
999 char curChar = rtf.charAt(i);
1000 if (curChar != '\\')
1001 {
1002 text.append(curChar);
1003 continue;
1004 }
1005
1006
1009 if (rtf.startsWith("\\pard", i)) {
1012 Element currentElement = (Element) stack.pop();
1013 currentElement.addContent(text.toString());
1014 text.delete(0, text.length());
1015 stack.clear();
1016 stack.push(div);
1017 i += (i + 5 < strlen && rtf.charAt(i + 5) == ' ') ? 5 : 4;
1018 continue;
1019 }
1020
1021 if (rtf.startsWith("\\par", i)) {
1024
1025 Element currentElement = (Element) stack.peek();
1026 currentElement.addContent(text.toString());
1027 text.delete(0, text.length());
1028 currentElement.addContent(OSISUtil.factory.createLB());
1029 i += (i + 4 < strlen && rtf.charAt(i + 4) == ' ') ? 4 : 3;
1030 continue;
1031 }
1032
1033 if (rtf.startsWith("\\qc", i)) {
1037 Element centerDiv = OSISUtil.factory.createDiv();
1038 centerDiv.setAttribute(OSIS_ATTR_TYPE, "x-center"); Element currentElement = (Element) stack.peek();
1040 currentElement.addContent(text.toString());
1041 text.delete(0, text.length());
1042 currentElement.addContent(centerDiv);
1043 stack.push(centerDiv);
1044 i += (i + 3 < strlen && rtf.charAt(i + 3) == ' ') ? 3 : 2;
1046 continue;
1047 }
1048
1049 if (rtf.startsWith("\\u", i)) {
1052 StringBuffer buf = new StringBuffer();
1053 i += 2;
1054 while (i < strlen)
1055 {
1056 char curDigit = rtf.charAt(i);
1057 if (curDigit != '-' && !Character.isDigit(curDigit))
1058 {
1059 break;
1060 }
1061 buf.append(curDigit);
1062 i++;
1063 }
1064 int value = Integer.parseInt(buf.toString());
1068 if (value < 0)
1069 {
1070 value += 65536;
1071 }
1072 text.append((char) value);
1073 continue;
1075 }
1076
1077 if (rtf.startsWith("\\i0", i) || rtf.startsWith("\\b0", i)) {
1080 Element currentElement = (Element) stack.pop();
1081 currentElement.addContent(text.toString());
1082 text.delete(0, text.length());
1083 i += (i + 3 < strlen && rtf.charAt(i + 3) == ' ') ? 3 : 2;
1084 continue;
1085 }
1086
1087 if (rtf.startsWith(" ", i) || rtf.startsWith("\n", i)) {
1090 i += 1;
1091 continue;
1092 }
1093
1094 if (rtf.startsWith("\\i", i)) {
1097 Element hiElement = OSISUtil.factory.createHI();
1098 hiElement.setAttribute(OSIS_ATTR_TYPE, HI_ITALIC);
1099 Element currentElement = (Element) stack.peek();
1100 currentElement.addContent(text.toString());
1101 text.delete(0, text.length());
1102 currentElement.addContent(hiElement);
1103 stack.push(hiElement);
1104 i += (i + 2 < strlen && rtf.charAt(i + 2) == ' ') ? 2 : 1;
1105 continue;
1106 }
1107
1108 if (rtf.startsWith("\\b", i)) {
1111 Element hiElement = OSISUtil.factory.createHI();
1112 hiElement.setAttribute(OSIS_ATTR_TYPE, HI_BOLD);
1113 Element currentElement = (Element) stack.peek();
1114 currentElement.addContent(text.toString());
1115 text.delete(0, text.length());
1116 currentElement.addContent(hiElement);
1117 stack.push(hiElement);
1118 i += (i + 2 < strlen && rtf.charAt(i + 2) == ' ') ? 2 : 1;
1119 continue;
1120 }
1121
1122 }
1123
1124 if (text.length() > 0)
1126 {
1127 div.addContent(text.toString());
1128 }
1129 return div.cloneContent();
1148 }
1149
1150
1154 private static void recurseDeepContent(Element start, String name, List reply)
1155 {
1156 if (start.getName().equals(name))
1157 {
1158 reply.add(start);
1159 }
1160
1161 Object data = null;
1162 Element ele = null;
1163 Iterator contentIter = start.getContent().iterator();
1164 while (contentIter.hasNext())
1165 {
1166 data = contentIter.next();
1167 if (data instanceof Element)
1168 {
1169 ele = (Element) data;
1170 recurseDeepContent(ele, name, reply);
1171 }
1172 }
1173 }
1174
1175
1179 private static void recurseElement(Object sub, StringBuffer buffer)
1180 {
1181 if (sub instanceof Text)
1182 {
1183 buffer.append(((Text) sub).getText());
1184 }
1185 else if (sub instanceof Element)
1186 {
1187 recurseChildren((Element) sub, buffer);
1188 }
1189 else
1190 {
1191 log.error("unknown type: " + sub.getClass().getName()); }
1193 }
1194
1195
1200 private static void recurseChildren(Element ele, StringBuffer buffer)
1201 {
1202 Iterator contentIter = ele.getContent().iterator();
1204 while (contentIter.hasNext())
1205 {
1206 Object sub = contentIter.next();
1207 recurseElement(sub, buffer);
1208 }
1209 }
1210
1211 private static String strongsNumber = "strong:([GgHh][0-9]+!?[A-Za-z]*)"; private static Pattern strongsNumberPattern = Pattern.compile(strongsNumber);
1213}
1214