[jsword-svn] r1348 - in trunk: bibledesktop/src/main/java/org/crosswire/bibledesktop/display/textpane common/src/main/java/org/crosswire/common/diff jsword/src/main/java/org/crosswire/jsword/book

dmsmith at www.crosswire.org dmsmith at www.crosswire.org
Thu May 24 12:10:02 MST 2007


Author: dmsmith
Date: 2007-05-24 12:10:01 -0700 (Thu, 24 May 2007)
New Revision: 1348

Added:
   trunk/common/src/main/java/org/crosswire/common/diff/package.html
Modified:
   trunk/bibledesktop/src/main/java/org/crosswire/bibledesktop/display/textpane/TextPaneBookDataDisplay.java
   trunk/common/src/main/java/org/crosswire/common/diff/Bitap.java
   trunk/common/src/main/java/org/crosswire/common/diff/CommonMiddle.java
   trunk/common/src/main/java/org/crosswire/common/diff/DiffCleanup.java
   trunk/common/src/main/java/org/crosswire/common/diff/DifferenceEngine.java
   trunk/common/src/main/java/org/crosswire/common/diff/LineMap.java
   trunk/common/src/main/java/org/crosswire/common/diff/Match.java
   trunk/common/src/main/java/org/crosswire/common/diff/Patch.java
   trunk/common/src/main/java/org/crosswire/common/diff/PatchEntry.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/BookData.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/Defaults.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/OSISUtil.java
Log:
Working example of diff in a parallel view.

Modified: trunk/bibledesktop/src/main/java/org/crosswire/bibledesktop/display/textpane/TextPaneBookDataDisplay.java
===================================================================
--- trunk/bibledesktop/src/main/java/org/crosswire/bibledesktop/display/textpane/TextPaneBookDataDisplay.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/bibledesktop/src/main/java/org/crosswire/bibledesktop/display/textpane/TextPaneBookDataDisplay.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -146,7 +146,7 @@
              * It appears that it is a line too long issue.
              */
             /* Apply the fix if the text is too long and we are not Java 1.5 or greater */
-            if (text.length() > 32768)
+            if (text.length() > 32768 && BookCategory.GENERAL_BOOK.equals(book.getBookCategory()))
             {
                 String javaVersion = System.getProperty("java.specification.version"); //$NON-NLS-1$
                 if (javaVersion == null || "1.5".compareTo(javaVersion) > 0) //$NON-NLS-1$

Modified: trunk/common/src/main/java/org/crosswire/common/diff/Bitap.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/Bitap.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/common/src/main/java/org/crosswire/common/diff/Bitap.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -283,4 +283,4 @@
      * Alphabet is the compiled representation of the pattern.
      */
     private Map alphabet;
-}
\ No newline at end of file
+}

Modified: trunk/common/src/main/java/org/crosswire/common/diff/CommonMiddle.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/CommonMiddle.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/common/src/main/java/org/crosswire/common/diff/CommonMiddle.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -88,7 +88,6 @@
         return targetSuffix;
     }
 
-    
     /* (non-Javadoc)
      * @see java.lang.Object#toString()
      */
@@ -112,13 +111,13 @@
      */
     public int hashCode()
     {
-        final int PRIME = 31;
+        final int prime = 31;
         int result = 1;
-        result = PRIME * result + ((sourcePrefix == null) ? 0 : sourcePrefix.hashCode());
-        result = PRIME * result + ((sourceSuffix == null) ? 0 : sourceSuffix.hashCode());
-        result = PRIME * result + ((targetPrefix == null) ? 0 : targetPrefix.hashCode());
-        result = PRIME * result + ((targetSuffix == null) ? 0 : targetSuffix.hashCode());
-        result = PRIME * result + ((commonality == null) ? 0 : commonality.hashCode());
+        result = prime * result + ((sourcePrefix == null) ? 0 : sourcePrefix.hashCode());
+        result = prime * result + ((sourceSuffix == null) ? 0 : sourceSuffix.hashCode());
+        result = prime * result + ((targetPrefix == null) ? 0 : targetPrefix.hashCode());
+        result = prime * result + ((targetSuffix == null) ? 0 : targetSuffix.hashCode());
+        result = prime * result + ((commonality == null) ? 0 : commonality.hashCode());
        return result;
     }
 
@@ -151,4 +150,4 @@
     private String targetPrefix;
     private String targetSuffix;
     private String commonality;
-}
\ No newline at end of file
+}

Modified: trunk/common/src/main/java/org/crosswire/common/diff/DiffCleanup.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/DiffCleanup.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/common/src/main/java/org/crosswire/common/diff/DiffCleanup.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -19,7 +19,6 @@
  *
  * ID: $Id$
  */
-
 package org.crosswire.common.diff;
 
 import java.util.List;
@@ -39,6 +38,13 @@
 public class DiffCleanup
 {
     /**
+     * Utility class constructor.
+     */
+    private DiffCleanup()
+    {
+    }
+
+    /**
      * Reduce the number of edits by eliminating semantically trivial equalities.
      * @param diffs List of Difference objects
      */
@@ -67,7 +73,7 @@
                 // an insertion or deletion
                 lengthChangesPost += curDiff.getText().length();
                 int lastLen = lastEquality != null ? lastEquality.length() : 0;
-                if (lastEquality != null && (lastLen <= lengthChangesPre) && (lastLen <= lengthChangesPost))
+                if (lastEquality != null && lastLen <= lengthChangesPre && lastLen <= lengthChangesPost)
                 {
                     // position pointer to the element after the one at the end of the stack
                     while (curDiff != equalities.lastElement())
@@ -81,7 +87,7 @@
                     // Insert a coresponding an insert.
                     pointer.add(new Difference(EditType.INSERT, lastEquality));
                     equalities.pop(); // Throw away the equality we just deleted;
-                    if ( !equalities.empty())
+                    if (!equalities.empty())
                     {
                         // Throw away the previous equality (it needs to be reevaluated).
                         equalities.pop();
@@ -213,7 +219,7 @@
                     }
                     else
                     {
-                        if ( !equalities.empty())
+                        if (!equalities.empty())
                         {
                             // Throw away the previous equality;
                             equalities.pop();
@@ -274,13 +280,13 @@
             EditType editType = curDiff.getEditType();
             if (EditType.INSERT.equals(editType))
             {
-                countInsert++ ;
+                countInsert++;
                 textInsert += curDiff.getText();
                 prevEqual = null;
             }
             else if (EditType.DELETE.equals(editType))
             {
-                countDelete++ ;
+                countDelete++;
                 textDelete += curDiff.getText();
                 prevEqual = null;
             }
@@ -380,7 +386,7 @@
      */
     public static void setEditCost(int newEditCost)
     {
-        editCost = newEditCost;        
+        editCost = newEditCost;
     }
 
     /**

Modified: trunk/common/src/main/java/org/crosswire/common/diff/DifferenceEngine.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/DifferenceEngine.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/common/src/main/java/org/crosswire/common/diff/DifferenceEngine.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -45,7 +45,7 @@
      */
     public DifferenceEngine()
     {
-        this("",""); //$NON-NLS-1$ //$NON-NLS-2$
+        this("", ""); //$NON-NLS-1$ //$NON-NLS-2$
     }
 
     /**

Modified: trunk/common/src/main/java/org/crosswire/common/diff/LineMap.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/LineMap.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/common/src/main/java/org/crosswire/common/diff/LineMap.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -158,4 +158,4 @@
      * The lines from the original. Useful for reconstitution.
      */
     private List lines;
-}
\ No newline at end of file
+}

Modified: trunk/common/src/main/java/org/crosswire/common/diff/Match.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/Match.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/common/src/main/java/org/crosswire/common/diff/Match.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -21,7 +21,6 @@
  */
 package org.crosswire.common.diff;
 
-
 /**
  * Computes the difference between two texts to create a patch.
  * Applies the patch onto another text, allowing for errors.
@@ -72,7 +71,7 @@
             // Nothing to match.
             return -1;
         }
-        
+
         if (text.equals(pattern))
         {
             // Shortcut (potentially not guaranteed by the algorithm)
@@ -108,6 +107,4 @@
      * The strategy for locating a best match.
      */
     private Locator locator;
-
-
-}
\ No newline at end of file
+}

Modified: trunk/common/src/main/java/org/crosswire/common/diff/Patch.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/Patch.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/common/src/main/java/org/crosswire/common/diff/Patch.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -1,3 +1,24 @@
+/**
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2007
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id$
+ */
 package org.crosswire.common.diff;
 
 import java.util.ArrayList;
@@ -6,6 +27,16 @@
 import java.util.ListIterator;
 import java.util.regex.Pattern;
 
+/**
+ * Marshals a patch to a list of Differences, Differences to a patch and applies a list of differences to text to patch it.
+ * 
+ * Based on the LGPL Diff_Match_Patch v1.5 javascript of Neil Fraser, Copyright (C) 2006
+ * <a href="http://neil.fraser.name/software/diff_match_patch/">http://neil.fraser.name/software/diff_match_patch/</a>
+ * 
+ * @see gnu.lgpl.License for license details.<br>
+ *      The copyright to this program is held by it's authors.
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
 public class Patch
 {
     /**
@@ -397,6 +428,10 @@
         return this;
     }
 
+    /**
+     * A holder of the results of a patch, with a results indicating
+     * which patch entries were able to be applied.
+     */
     public static class PatchResults
     {
         /**

Modified: trunk/common/src/main/java/org/crosswire/common/diff/PatchEntry.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/PatchEntry.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/common/src/main/java/org/crosswire/common/diff/PatchEntry.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -1,3 +1,24 @@
+/**
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2007
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id$
+ */
 package org.crosswire.common.diff;
 
 import java.util.ArrayList;
@@ -6,6 +27,17 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+/**
+ * A PatchEntry is a single "instruction" in a Patch, consisting of a interval over which differences
+ * are applied and the differences that should be applied.
+ * 
+ * Based on the LGPL Diff_Match_Patch v1.5 javascript of Neil Fraser, Copyright (C) 2006
+ * <a href="http://neil.fraser.name/software/diff_match_patch/">http://neil.fraser.name/software/diff_match_patch/</a>
+ * 
+ * @see gnu.lgpl.License for license details.<br>
+ *      The copyright to this program is held by it's authors.
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
 public class PatchEntry
 {
     //  Constructor for a patch object.
@@ -174,7 +206,7 @@
         else
         {
             leftStart--;
-            leftLength =Integer.parseInt(matcher.group(2));
+            leftLength = Integer.parseInt(matcher.group(2));
         }
 
         rightStart = Integer.parseInt(matcher.group(3));

Added: trunk/common/src/main/java/org/crosswire/common/diff/package.html
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/diff/package.html	                        (rev 0)
+++ trunk/common/src/main/java/org/crosswire/common/diff/package.html	2007-05-24 19:10:01 UTC (rev 1348)
@@ -0,0 +1,9 @@
+<html>
+<body>
+
+<p>
+  An implementation of Diff that works within the line.
+</p>
+
+</body>
+</html>

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/BookData.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/BookData.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/BookData.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -22,13 +22,17 @@
 package org.crosswire.jsword.book;
 
 import java.util.Iterator;
+import java.util.List;
 
+import org.crosswire.common.diff.Diff;
+import org.crosswire.common.diff.DiffCleanup;
 import org.crosswire.common.xml.JDOMSAXEventProvider;
 import org.crosswire.common.xml.SAXEventProvider;
 import org.crosswire.jsword.passage.Key;
 import org.jdom.Content;
 import org.jdom.Document;
 import org.jdom.Element;
+import org.jdom.Text;
 
 /**
  * BookData is the assembler of the osis that is returned by the filters.
@@ -56,9 +60,9 @@
         this.key = key;
 
         Book defaultBible = Defaults.getBible();
-        if (defaultBible != null &&
-            BookCategory.BIBLE.equals(book.getBookCategory()) &&
-            !defaultBible.equals(book)
+        if (defaultBible != null
+            && BookCategory.BIBLE.equals(book.getBookCategory())
+            && !defaultBible.equals(book)
            )
         {
             books = new Book[2];
@@ -154,16 +158,52 @@
         }
         else
         {
+            Element table = OSISUtil.factory().createTable();
+            Element row = OSISUtil.factory().createRow();
+            Element cell = null;
+
+            table.addContent(row);
+
             Iterator[] iters = new Iterator[books.length];
+            boolean[] showDiffs = new boolean[books.length - 1];
+            boolean doDiffs = false;
+
             for (int i = 0; i < books.length; i++)
             {
-                iters[i] = books[i].getOsisIterator(key, true);
+                Book book = books[i];
+
+                cell = OSISUtil.factory().createHeaderCell();
+
+                if (i > 0)
+                {
+                    Book prevBook = books[i - 1];
+                    BookCategory category = book.getBookCategory();
+
+                    BookCategory prevCategory = prevBook.getBookCategory();
+                    showDiffs[i - 1] = BookCategory.BIBLE.equals(category)
+                    && category.equals(prevCategory)
+                    && book.getLanguage().equals(prevBook.getLanguage());
+                    if (showDiffs[i - 1])
+                    {
+                        doDiffs = true;
+                        StringBuffer buf = new StringBuffer(prevBook.getInitials());
+                        buf.append(" ==> "); //$NON-NLS-1$
+                        buf.append(book.getInitials());
+
+                        cell.addContent(OSISUtil.factory().createText(buf.toString()));
+                        row.addContent(cell);
+                        cell = OSISUtil.factory().createHeaderCell();
+                    }
+                }
+
+                cell.addContent(OSISUtil.factory().createText(book.getInitials()));
+                row.addContent(cell);
+
+                iters[i] = book.getOsisIterator(key, true);
             }
 
             Content content = null;
-            Element table = OSISUtil.factory().createTable();
-            Element row = null;
-            Element cell = null;
+
             int cellCount = 0;
             int rowCount = 0;
             while (true)
@@ -172,6 +212,8 @@
 
                 row = OSISUtil.factory().createRow();
 
+                String lastText = ""; //$NON-NLS-1$
+
                 for (int i = 0; i < iters.length; i++)
                 {
                     cell = OSISUtil.factory().createCell();
@@ -179,6 +221,31 @@
                     if (iters[i].hasNext())
                     {
                         content = (Content) iters[i].next();
+
+                        if (doDiffs)
+                        {
+                            String thisText = ""; //$NON-NLS-1$                        
+                            if (content instanceof Element)
+                            {
+                                thisText = OSISUtil.getCanonicalText((Element)content);
+                            }
+                            else if (content instanceof Text)
+                            {
+                                thisText = ((Text) content).getText();
+                            }
+
+                            if (i > 0 && showDiffs[i - 1])
+                            {
+                                List diffs = new Diff(lastText, thisText, false).compare();
+                                DiffCleanup.cleanupSemantic(diffs);
+                                cell.addContent(OSISUtil.diffToOsis(diffs));
+
+                                // Since we used that cell create another
+                                cell = OSISUtil.factory().createCell();
+                                row.addContent(cell);
+                            }
+                            lastText = thisText;
+                        }
                         cell.addContent(content);
                         cellCount++;
                     }

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/Defaults.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/Defaults.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/Defaults.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -580,7 +580,7 @@
     /**
      * The current bible being tracked.
      */
-    private static Book currentBible = null;
+    private static Book currentBible;
 
     /**
      * The default Bible

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/OSISUtil.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/OSISUtil.java	2007-05-24 14:27:32 UTC (rev 1347)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/OSISUtil.java	2007-05-24 19:10:01 UTC (rev 1348)
@@ -31,6 +31,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.crosswire.common.diff.Difference;
+import org.crosswire.common.diff.EditType;
 import org.crosswire.common.util.Logger;
 import org.crosswire.jsword.passage.Key;
 import org.crosswire.jsword.passage.KeyFactory;
@@ -214,11 +216,26 @@
     public static final String Q_EMBEDDED = "embedded"; //$NON-NLS-1$
 
     /**
-     * Constant to help narrow down what dvwe use "list" for.
+     * Constant to help narrow down what we use "list" for.
      */
     public static final String LIST_ORDERED = "x-ordered"; //$NON-NLS-1$
     public static final String LIST_UNORDERED = "x-unordered"; //$NON-NLS-1$
 
+    /**
+     * Table roles (on table, row and cell elements) can be "data", the default, or label.
+     */
+    public static final String TABLE_ROLE_LABEL = "label"; //$NON-NLS-1$
+
+    /**
+     * Possible cell alignments
+     */
+    public static final String CELL_ALIGN_LEFT = "left"; //$NON-NLS-1$
+    public static final String CELL_ALIGN_RIGHT = "right"; //$NON-NLS-1$
+    public static final String CELL_ALIGN_CENTER = "center"; //$NON-NLS-1$
+    public static final String CELL_ALIGN_JUSTIFY = "justify"; //$NON-NLS-1$
+    public static final String CELL_ALIGN_START = "start"; //$NON-NLS-1$
+    public static final String CELL_ALIGN_END = "end"; //$NON-NLS-1$
+
     public static final String OSIS_ELEMENT_TITLE = "title"; //$NON-NLS-1$
     public static final String OSIS_ELEMENT_TABLE = "table"; //$NON-NLS-1$
     public static final String OSIS_ELEMENT_SPEECH = "speech"; //$NON-NLS-1$
@@ -255,7 +272,10 @@
     public static final String OSIS_ATTR_EID = "eID"; //$NON-NLS-1$
     public static final String ATTRIBUTE_W_LEMMA = "lemma"; //$NON-NLS-1$
     public static final String ATTRIBUTE_FIGURE_SRC = "src"; //$NON-NLS-1$
+    public static final String ATTRIBUTE_TABLE_ROLE = "role"; //$NON-NLS-1$
+    public static final String ATTRIBUTE_CELL_ALIGN = "align"; //$NON-NLS-1$
     public static final String OSIS_ATTR_TYPE = "type"; //$NON-NLS-1$
+    public static final String OSIS_ATTR_CANONICAL = "canonical"; //$NON-NLS-1$
     public static final String OSIS_ATTR_SUBTYPE = "subType"; //$NON-NLS-1$
     public static final String OSIS_ATTR_REF = "osisRef"; //$NON-NLS-1$
     public static final String OSIS_ATTR_LEVEL = "level"; //$NON-NLS-1$
@@ -274,7 +294,7 @@
 
     private static final Set EXTRA_BIBLICAL_ELEMENTS = new HashSet(Arrays.asList(new String[]
     {
-        OSIS_ELEMENT_NOTE,
+        OSIS_ELEMENT_NOTE, OSIS_ELEMENT_TITLE, OSIS_ELEMENT_REFERENCE
     }));
 
     /**
@@ -363,6 +383,17 @@
         /**
          * 
          */
+        public Element createHeaderCell()
+        {
+            Element ele = new Element(OSIS_ELEMENT_CELL);
+            ele.setAttribute(ATTRIBUTE_TABLE_ROLE, TABLE_ROLE_LABEL);
+            ele.setAttribute(ATTRIBUTE_CELL_ALIGN, CELL_ALIGN_CENTER);
+            return ele;
+        }
+
+        /**
+         * 
+         */
         public Element createVerse()
         {
             return new Element(OSIS_ELEMENT_VERSE);
@@ -608,18 +639,24 @@
             if (data instanceof Element)
             {
                 ele = (Element) data;
-//                if (ele.getName().equals(OSISUtil.OSIS_ELEMENT_VERSE))
-//                {
+                if (!isCanonical(ele))
+                {
+                    continue;
+                }
+
+                if (ele.getName().equals(OSISUtil.OSIS_ELEMENT_VERSE))
+                {
                     sID = ele.getAttributeValue(OSISUtil.OSIS_ATTR_SID);
-                    if (sID != null)
-                    {
-                        getCanonicalContent(ele.getName(), sID, dit, buffer);
-                    }
-                    else
-                    {
-                        getCanonicalContent(ele.getName(), null, ele.getContent().iterator(), buffer);
-                    }
-//                }
+                }
+
+                if (sID != null)
+                {
+                    getCanonicalContent(ele, sID, dit, buffer);
+                }
+                else
+                {
+                    getCanonicalContent(ele, null, ele.getContent().iterator(), buffer);
+                }
             }
             else if (data instanceof Text)
             {
@@ -761,14 +798,19 @@
         while (contentIter.hasNext())
         {
             Element ele = (Element) contentIter.next();
-            getCanonicalContent(ele.getName(), null, ele.getContent().iterator(), buffer);
+            getCanonicalContent(ele, null, ele.getContent().iterator(), buffer);
         }
 
         return buffer.toString();
     }
 
-    private static void getCanonicalContent(String sName, String sID, Iterator iter, StringBuffer buffer)
+    private static void getCanonicalContent(Element parent, String sID, Iterator iter, StringBuffer buffer)
     {
+        if (!isCanonical(parent))
+        {
+            return;
+        }
+
         Object data = null;
         Element ele = null;
         String eleName = null;
@@ -783,16 +825,11 @@
                 // This should be a eID=, that matches sID, from the same element.
                 eleName = ele.getName();
                 eID = ele.getAttributeValue(OSISUtil.OSIS_ATTR_SID);
-                if (eID != null && eID.equals(sID) && eleName.equals(sName))
+                if (eID != null && eID.equals(sID) && eleName.equals(parent.getName()))
                 {
                     break;
                 }
-
-                // Ignore extra-biblical text
-                if (!EXTRA_BIBLICAL_ELEMENTS.contains(eleName))
-                {
-                    OSISUtil.getCanonicalContent(sName, sID, ele.getContent().iterator(), buffer);
-                }
+                OSISUtil.getCanonicalContent(ele, sID, ele.getContent().iterator(), buffer);
             }
             else if (data instanceof Text)
             {
@@ -801,6 +838,24 @@
         }
     }
 
+    private static boolean isCanonical(Content content)
+    {
+        boolean result = true;
+        if (content instanceof Element)
+        {
+            Element element = (Element) content;
+            
+            // Ignore extra-biblical text
+            if (EXTRA_BIBLICAL_ELEMENTS.contains(element.getName()))
+            {
+                String canonical = element.getAttributeValue(OSISUtil.OSIS_ATTR_CANONICAL);
+                result = Boolean.valueOf(canonical).booleanValue();
+            }
+        }
+        
+        return result;
+    }
+
     private static String getTextContent(List fragment)
     {
         StringBuffer buffer = new StringBuffer();
@@ -883,6 +938,43 @@
     }
 
     /**
+     * Convert a Difference list into a pretty HTML report.
+     * @param diffs List of Difference objects
+     * @return HTML representation
+     */
+    public static List diffToOsis(List diffs)
+    {
+        Element div = factory().createDiv();
+        
+        for (int x = 0; x < diffs.size(); x++)
+        {
+            Difference diff = (Difference) diffs.get(x);
+            EditType editType = diff.getEditType(); // Mode (delete, equal, insert)
+            Text text = factory.createText(diff.getText()); // Text of change.
+
+            if (EditType.DELETE.equals(editType))
+            {
+                Element hi = factory().createHI();
+                hi.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.HI_LINETHROUGH);
+                hi.addContent(text);
+                div.addContent(hi);
+            }
+            else if (EditType.INSERT.equals(editType))
+            {
+                Element hi = factory().createHI();
+                hi.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.HI_UNDERLINE);
+                hi.addContent(text);
+                div.addContent(hi);
+            }
+            else
+            {
+                div.addContent(text);
+            }
+        }
+        return div.cloneContent();
+    }
+
+    /**
      * Find all the instances of elements of type <code>find</code> under
      * the element <code>div</code>. For internal use only.
      */




More information about the jsword-svn mailing list