1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2005 - 2012
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: SyncTag.java 2221 2012-01-25 21:32:57Z dmsmith $
21   */
22  package org.crosswire.jsword.book.filter.thml;
23  
24  import java.util.List;
25  
26  import org.crosswire.jsword.book.Book;
27  import org.crosswire.jsword.book.DataPolice;
28  import org.crosswire.jsword.book.OSISUtil;
29  import org.crosswire.jsword.passage.Key;
30  import org.jdom.Content;
31  import org.jdom.Element;
32  import org.jdom.Text;
33  import org.xml.sax.Attributes;
34  
35  /**
36   * THML Tag to process the sync element. A sync tag is always empty and
37   * immediately follows what it marks. With types of Strong's and morph these are
38   * to become w elements that surround the word that they modify. This requires
39   * that we find the last text element and surround it with a w element. If the
40   * last text element is already surrounded with a w element then this is added
41   * to it. As a simplifying assumption, we will assume that the text element is
42   * not contained by anything except perhaps by a w element.
43   * 
44   * @see gnu.lgpl.License for license details.<br>
45   *      The copyright to this program is held by it's authors.
46   * @author Joe Walker [joe at eireneh dot com]
47   */
48  public class SyncTag extends AbstractTag {
49      /* (non-Javadoc)
50       * @see org.crosswire.jsword.book.filter.thml.Tag#getTagName()
51       */
52      public String getTagName() {
53          return "sync";
54      }
55  
56      @Override
57      public Element processTag(Book book, Key key, Element ele, Attributes attrs) {
58          // Strong's reference
59          String type = attrs.getValue("type");
60          String value = attrs.getValue("value");
61  
62          if ("Strongs".equals(type)) {
63              List<Content> siblings = ele.getContent();
64              int size = siblings.size();
65              if (size == 0) {
66                  return null;
67              }
68              Content lastEle = siblings.get(size - 1);
69              if (lastEle instanceof Text) {
70                  Element w = OSISUtil.factory().createW();
71                  w.setAttribute(OSISUtil.ATTRIBUTE_W_LEMMA, OSISUtil.LEMMA_STRONGS + value);
72                  siblings.set(size - 1, w);
73                  w.addContent(lastEle);
74              } else if (lastEle instanceof Element) {
75                  Element wEle = (Element) lastEle;
76                  if (wEle.getName().equals(OSISUtil.OSIS_ELEMENT_W)) {
77                      StringBuilder buf = new StringBuilder();
78                      String strongsAttr = wEle.getAttributeValue(OSISUtil.ATTRIBUTE_W_LEMMA);
79                      if (strongsAttr != null) {
80                          buf.append(strongsAttr);
81                          buf.append(' ');
82                      }
83                      buf.append(OSISUtil.LEMMA_STRONGS);
84                      buf.append(value);
85                      wEle.setAttribute(OSISUtil.ATTRIBUTE_W_LEMMA, buf.toString());
86                  }
87              }
88              return null;
89          }
90  
91          if ("morph".equals(type)) {
92              List<Content> siblings = ele.getContent();
93              int size = siblings.size();
94              if (size == 0) {
95                  return null;
96              }
97              Content lastEle = siblings.get(size - 1);
98              if (lastEle instanceof Text) {
99                  Element w = OSISUtil.factory().createW();
100                 w.setAttribute(OSISUtil.ATTRIBUTE_W_MORPH, OSISUtil.MORPH_ROBINSONS + value);
101                 siblings.set(size - 1, w);
102                 w.addContent(lastEle);
103             } else if (lastEle instanceof Element) {
104                 Element wEle = (Element) lastEle;
105                 if (wEle.getName().equals(OSISUtil.OSIS_ELEMENT_W)) {
106                     StringBuilder buf = new StringBuilder();
107                     String strongsAttr = wEle.getAttributeValue(OSISUtil.ATTRIBUTE_W_MORPH);
108                     if (strongsAttr != null) {
109                         buf.append(strongsAttr);
110                         buf.append(' ');
111                     }
112                     buf.append(OSISUtil.MORPH_ROBINSONS);
113                     buf.append(value);
114                     wEle.setAttribute(OSISUtil.ATTRIBUTE_W_MORPH, buf.toString());
115                 }
116             }
117             return null;
118         }
119 
120         if ("Dict".equals(type)) {
121             Element div = OSISUtil.factory().createDiv();
122             div.setAttribute(OSISUtil.OSIS_ATTR_OSISID, "dict://" + value);
123 
124             if (ele != null) {
125                 ele.addContent(div);
126             }
127 
128             return div;
129         }
130 
131         DataPolice.report(book, key, "sync tag has type=" + type + " when value=" + value);
132         return null;
133     }
134 }
135