[Tynstep-svn] r171 - in trunk: step-web-app/src/main/java/com/tyndalehouse/step/web/client/bundles/css step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/widgets step-web-app/src/main/java/com/tyndalehouse/step/web/client/view step-web-app/src/main/resources/com/tyndalehouse/step/web/client/css step-web-server/src/main/java/com/tyndalehouse/step/web/server/handler step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture step-web-shared/src/test/java/com/tyndalehouse/step/web/shared step-web-shared/src/test/java/com/tyndalehouse/step/web/shared/scripture

ChrisBurrell at crosswire.org ChrisBurrell at crosswire.org
Sun Aug 8 04:22:05 MST 2010


Author: ChrisBurrell
Date: 2010-08-08 04:22:05 -0700 (Sun, 08 Aug 2010)
New Revision: 171

Added:
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils/ArrayUtils.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassageDisplay.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScriptureDisplay.java
   trunk/step-web-shared/src/test/java/com/tyndalehouse/step/web/shared/scripture/
   trunk/step-web-shared/src/test/java/com/tyndalehouse/step/web/shared/scripture/PassageElementTest.java
Removed:
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassagePresenterDisplay.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScripturePresenterDisplay.java
Modified:
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/bundles/css/Passage.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils/StringUtils.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/PassagePresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScripturePresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/widgets/HighlightableLabel.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/PassageView.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureView.java
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/client/css/passage.css
   trunk/step-web-server/src/main/java/com/tyndalehouse/step/web/server/handler/GetCurrentBibleTextHandler.java
   trunk/step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture/Passage.java
   trunk/step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture/PassageElement.java
Log:
first draft of the reverse interlinear

Modified: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/bundles/css/Passage.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/bundles/css/Passage.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/bundles/css/Passage.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -22,4 +22,8 @@
 
     String highlight();
 
+    String interlinear();
+
+    String interlinearTitle();
+
 }

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils/ArrayUtils.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils/ArrayUtils.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils/ArrayUtils.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -0,0 +1,14 @@
+package com.tyndalehouse.step.web.client.framework.utils;
+
+public class ArrayUtils {
+    /**
+     * returns true if array is null or length == 0
+     * 
+     * @param o
+     *            the array
+     * @return true if array is null or length == 0
+     */
+    public boolean isEmpty(final Object[] o) {
+        return o == null || o.length == 0;
+    }
+}

Modified: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils/StringUtils.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils/StringUtils.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/framework/utils/StringUtils.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -14,7 +14,7 @@
      * @return true if s == null or s.length == 0
      */
     public static boolean isEmpty(final String s) {
-        return s == null || s.length() == 0;
+        return s == null || s.length() == 0 || s.trim().length() == 0;
     }
 
     /**

Modified: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/PassagePresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/PassagePresenter.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/PassagePresenter.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -2,8 +2,11 @@
 
 import static com.tyndalehouse.step.web.client.framework.utils.OsisUtils.getVerseNumberFromOsisId;
 import static com.tyndalehouse.step.web.client.framework.utils.StringUtils.isNotEmpty;
+import static com.tyndalehouse.step.web.shared.common.ScriptureDisplayOptions.REVERSE_INTERLINEAR;
 import static com.tyndalehouse.step.web.shared.common.ScriptureDisplayOptions.VERSE_NUMBERS;
+import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.ALTERNATIVE_WORDING;
 import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.LEMMA;
+import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.MORPH;
 import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.OSIS_ID;
 import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.VERSE;
 
@@ -25,7 +28,7 @@
 import com.mvp4g.client.annotation.Presenter;
 import com.mvp4g.client.presenter.BasePresenter;
 import com.tyndalehouse.step.web.client.framework.StepEventBus;
-import com.tyndalehouse.step.web.client.presenter.display.PassagePresenterDisplay;
+import com.tyndalehouse.step.web.client.presenter.display.PassageDisplay;
 import com.tyndalehouse.step.web.client.toolkit.handlers.OptionEvent;
 import com.tyndalehouse.step.web.client.toolkit.handlers.OptionHandler;
 import com.tyndalehouse.step.web.client.view.PassageView;
@@ -38,7 +41,7 @@
 import com.tyndalehouse.step.web.shared.scripture.PassageElement;
 
 @Presenter(view = PassageView.class, multiple = true)
-public class PassagePresenter extends BasePresenter<PassagePresenterDisplay, StepEventBus> {
+public class PassagePresenter extends BasePresenter<PassageDisplay, StepEventBus> {
     private final DispatchAsync dispatcher;
 
     /** The currently displayed passage */
@@ -146,8 +149,15 @@
      */
     void renderPassage() {
         final Map<String, ScriptureDisplayOptions> selectedOptions = view.getSelectedOptions();
+        Log.info("" + System.currentTimeMillis());
         view.clearPassage();
-        Log.info("" + System.currentTimeMillis());
+
+        if (selectedOptions.get(REVERSE_INTERLINEAR.getKey()) == REVERSE_INTERLINEAR) {
+            view.setNumLines(4);
+        } else {
+            view.setNumLines(1);
+        }
+
         final List<PassageElement> passageElements = passage.getRootPassageNode().getChildren();
 
         for (final PassageElement passageElement : passageElements) {
@@ -184,26 +194,7 @@
                 break;
             case WORD:
             case TEXT:
-                final HasClickAndHighlightHandlers wordHandler = view.createText(getText(passageElement));
-
-                final String lemmaAttribute = passageElement.getAttribute(OsisElementType.LEMMA);
-                if (lemmaAttribute != null) {
-                    // IMPROVEMENT: this could happen server side, and save
-                    // ops in the browser
-                    final String[] lemmas = lemmaAttribute.split(" ");
-                    for (int ii = 0; ii < lemmas.length; ii++) {
-                        if (selectedOptions.containsKey(ScriptureDisplayOptions.SHOW_LEMMAS.name())) {
-                            view.createLemmaTag(lemmas[ii].replaceAll("strong:", ""));
-                        }
-                        addHighlitableWord(lemmas[ii], wordHandler);
-                    }
-
-                    wordHandler.addClickHandler(new ClickHandler() {
-                        public void onClick(final ClickEvent clickEvent) {
-                            getEventBus().selectedLemmas(lemmas);
-                        }
-                    });
-                }
+                doWord(passageElement, selectedOptions);
                 break;
             case LINE_BREAK:
                 view.createLineBreak();
@@ -228,6 +219,67 @@
     }
 
     /**
+     * business logic around translating a passage element into a word to be
+     * displayed on the screen
+     * 
+     * @param passageElement
+     *            the passageElement
+     * @param selectedOptions
+     *            the selectedOptions currently on the screen.
+     */
+    void doWord(final PassageElement passageElement, final Map<String, ScriptureDisplayOptions> selectedOptions) {
+        final String alternativeWording = passageElement.getAttribute(ALTERNATIVE_WORDING);
+        final String lemmaAttribute = passageElement.getAttribute(LEMMA);
+        final String morphAttribute = passageElement.getAttribute(MORPH);
+        final String[] lemmas = getArrayOfAttributes(lemmaAttribute, "strong:");
+        final String[] morphs = getArrayOfAttributes(morphAttribute, "robinson:");
+        final HasClickAndHighlightHandlers wordHandler;
+        final String[] fullLemmas = lemmaAttribute != null ? lemmaAttribute.split(" ") : new String[0];
+
+        if (selectedOptions.get(REVERSE_INTERLINEAR.getKey()) == REVERSE_INTERLINEAR) {
+            wordHandler = view.createInterlinearWord(getText(passageElement), alternativeWording, lemmas, morphs);
+        } else {
+            wordHandler = view.createText(getText(passageElement));
+        }
+
+        for (int ii = 0; ii < lemmas.length; ii++) {
+            if (selectedOptions.containsKey(ScriptureDisplayOptions.SHOW_LEMMAS.getKey())) {
+                view.createLemmaTag(lemmas[ii]);
+            }
+            addHighlitableWord(fullLemmas[ii], wordHandler);
+        }
+
+        if (wordHandler != null) {
+            wordHandler.addClickHandler(new ClickHandler() {
+                public void onClick(final ClickEvent clickEvent) {
+                    getEventBus().selectedLemmas(fullLemmas);
+                }
+            });
+        }
+    }
+
+    /**
+     * turns a list of osis, prefixed attributes into an array
+     * 
+     * @param attributeArray
+     *            the attribute array
+     * @param prefix
+     *            the prefix of each attribute, which gets removed
+     * @return an array of attributes without the prefix
+     */
+    String[] getArrayOfAttributes(final String attributeArray, final String prefix) {
+        if (attributeArray == null) {
+            return new String[0];
+        }
+
+        final String[] attributes = attributeArray.split(" ");
+        for (int ii = 0; ii < attributes.length; ii++) {
+            attributes[ii] = attributes[ii].replace(prefix, "");
+        }
+        return attributes;
+    }
+
+    /**
      * safely adds a word to the highlightable map
      * 
      * @param lemma
@@ -236,12 +288,15 @@
      *            a word which can be highlighted
      */
     void addHighlitableWord(final String lemma, final HasClickAndHighlightHandlers wordHandler) {
-        List<HasClickAndHighlightHandlers> words = this.highlightableWords.get(lemma);
-        if (words == null) {
-            words = new ArrayList<HasClickAndHighlightHandlers>();
-            this.highlightableWords.put(lemma, words);
+        if (wordHandler != null) {
+
+            List<HasClickAndHighlightHandlers> words = this.highlightableWords.get(lemma);
+            if (words == null) {
+                words = new ArrayList<HasClickAndHighlightHandlers>();
+                this.highlightableWords.put(lemma, words);
+            }
+            words.add(wordHandler);
         }
-        words.add(wordHandler);
     }
 
     /**

Modified: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScripturePresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScripturePresenter.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScripturePresenter.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -16,7 +16,7 @@
 import com.mvp4g.client.presenter.BasePresenter;
 import com.tyndalehouse.step.web.client.framework.ScripturePresenterPosition;
 import com.tyndalehouse.step.web.client.framework.StepEventBus;
-import com.tyndalehouse.step.web.client.presenter.display.ScripturePresenterDisplay;
+import com.tyndalehouse.step.web.client.presenter.display.ScriptureDisplay;
 import com.tyndalehouse.step.web.client.view.ScriptureView;
 import com.tyndalehouse.step.web.shared.command.GetAvailableBibleVersionsCommand;
 import com.tyndalehouse.step.web.shared.result.GetAvailableBibleVersionsResult;
@@ -34,7 +34,7 @@
 // everything else...
 
 @Presenter(view = ScriptureView.class, multiple = true)
-public class ScripturePresenter extends BasePresenter<ScripturePresenterDisplay, StepEventBus> {
+public class ScripturePresenter extends BasePresenter<ScriptureDisplay, StepEventBus> {
 
     /** default asynchronous dispatcher */
     private final DispatchAsync dispatcher;

Copied: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassageDisplay.java (from rev 166, trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassagePresenterDisplay.java)
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassageDisplay.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassageDisplay.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -0,0 +1,93 @@
+package com.tyndalehouse.step.web.client.presenter.display;
+
+import java.util.Map;
+
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.tyndalehouse.step.web.client.framework.StepViewInterface;
+import com.tyndalehouse.step.web.client.toolkit.handlers.OptionHandler;
+import com.tyndalehouse.step.web.client.view.handlers.HasClickAndHighlightHandlers;
+import com.tyndalehouse.step.web.shared.common.ScriptureDisplayOptions;
+
+/**
+ * contract for passage views
+ * 
+ * @author CJBurrell
+ * 
+ */
+public interface PassageDisplay extends StepViewInterface {
+    /** empties the passage view */
+    void clearPassage();
+
+    /** creates a verse */
+    void createVerse();
+
+    /**
+     * creates a portion of text on the view
+     */
+    HasClickAndHighlightHandlers createText(String text);
+
+    /** creates a line break */
+    void createLineBreak();
+
+    /** creates a quote on the passage */
+    void createQuote(String text);
+
+    /** creates a translator's change */
+    void createTransChange(String text);
+
+    /** creates a title */
+    void createTitle(String text);
+
+    /**
+     * creates a verse number
+     * 
+     * @param verseNumber
+     *            the verse number
+     * */
+    void createVerseNumber(String verseNumber);
+
+    /**
+     * creates a lemma on the view
+     * 
+     * @param lemma
+     *            the lemma
+     */
+
+    void createLemmaTag(String lemma);
+
+    /**
+     * adds a handler to the button that switches options
+     * 
+     * @param optionHandler
+     * @return
+     */
+    HandlerRegistration addOptionHandler(OptionHandler optionHandler);
+
+    /**
+     * gets the current list of selected options
+     * 
+     * @return
+     */
+    Map<String, ScriptureDisplayOptions> getSelectedOptions();
+
+    /**
+     * creates a four-lined interlinear word
+     * 
+     * @param text
+     *            the text to be displayed
+     * @param alternativeWording
+     *            the word to be displayed as the alternative
+     * @param lemmas
+     *            the lemmas associated with this word
+     * @param morphs
+     *            the morphs associated with this word
+     * @return a handler to enable the highlighting of the word
+     */
+    HasClickAndHighlightHandlers createInterlinearWord(String text, String alternativeWording, String[] lemmas,
+            String[] morphs);
+
+    /**
+     * sets the expected number of lines in the interlinear
+     */
+    void setNumLines(int i);
+}
\ No newline at end of file

Deleted: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassagePresenterDisplay.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassagePresenterDisplay.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/PassagePresenterDisplay.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -1,70 +0,0 @@
-package com.tyndalehouse.step.web.client.presenter.display;
-
-import java.util.Map;
-
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.tyndalehouse.step.web.client.framework.StepViewInterface;
-import com.tyndalehouse.step.web.client.toolkit.handlers.OptionHandler;
-import com.tyndalehouse.step.web.client.view.handlers.HasClickAndHighlightHandlers;
-import com.tyndalehouse.step.web.shared.common.ScriptureDisplayOptions;
-
-/**
- * contract for passage views
- * 
- * @author CJBurrell
- * 
- */
-public interface PassagePresenterDisplay extends StepViewInterface {
-    /** empties the passage view */
-    void clearPassage();
-
-    /** creates a verse */
-    void createVerse();
-
-    /** creates a portion of text on the view */
-    HasClickAndHighlightHandlers createText(String text);
-
-    /** creates a line break */
-    void createLineBreak();
-
-    /** creates a quote on the passage */
-    void createQuote(String text);
-
-    /** creates a translator's change */
-    void createTransChange(String text);
-
-    /** creates a title */
-    void createTitle(String text);
-
-    /**
-     * creates a verse number
-     * 
-     * @param verseNumber
-     *            the verse number
-     * */
-    void createVerseNumber(String verseNumber);
-
-    /**
-     * creates a lemma on the view
-     * 
-     * @param lemma
-     *            the lemma
-     */
-
-    void createLemmaTag(String lemma);
-
-    /**
-     * adds a handler to the button that switches options
-     * 
-     * @param optionHandler
-     * @return
-     */
-    HandlerRegistration addOptionHandler(OptionHandler optionHandler);
-
-    /**
-     * gets the current list of selected options
-     * 
-     * @return
-     */
-    Map<String, ScriptureDisplayOptions> getSelectedOptions();
-}
\ No newline at end of file

Copied: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScriptureDisplay.java (from rev 166, trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScripturePresenterDisplay.java)
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScriptureDisplay.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScriptureDisplay.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -0,0 +1,43 @@
+package com.tyndalehouse.step.web.client.presenter.display;
+
+import com.google.gwt.event.logical.shared.HasSelectionHandlers;
+import com.google.gwt.user.client.ui.TreeItem;
+import com.tyndalehouse.step.web.client.framework.StepViewInterface;
+
+/**
+ * Description of the view for presenting scripture to the user
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface ScriptureDisplay extends StepViewInterface {
+    // IMPROVEMENT: move methods for options button into its own widget, and
+    // same for version selector, all on the same child event bus
+    /**
+     * adds a version to the display
+     * 
+     * @param contentType
+     *            the type of content this is, for example Bible
+     * @param language
+     *            the language
+     * @param versionInitials
+     *            the initials of the version
+     * @param versionName
+     *            the version name
+     */
+    void addVersion(String contentType, String language, String versionInitials, String versionName);
+
+    /**
+     * the version selector widget
+     * 
+     * @return the handler to register events to
+     */
+    HasSelectionHandlers<TreeItem> getVersionSelector();
+
+    /**
+     * @return the initials of the current bible version
+     */
+    String getCurrentlySelectedVersion();
+
+    void setScriptureHolder(StepViewInterface view);
+}
\ No newline at end of file

Deleted: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScripturePresenterDisplay.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScripturePresenterDisplay.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/display/ScripturePresenterDisplay.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -1,43 +0,0 @@
-package com.tyndalehouse.step.web.client.presenter.display;
-
-import com.google.gwt.event.logical.shared.HasSelectionHandlers;
-import com.google.gwt.user.client.ui.TreeItem;
-import com.tyndalehouse.step.web.client.framework.StepViewInterface;
-
-/**
- * Description of the view for presenting scripture to the user
- * 
- * @author cjburrell
- * 
- */
-public interface ScripturePresenterDisplay extends StepViewInterface {
-    // IMPROVEMENT: move methods for options button into its own widget, and
-    // same for version selector, all on the same child event bus
-    /**
-     * adds a version to the display
-     * 
-     * @param contentType
-     *            the type of content this is, for example Bible
-     * @param language
-     *            the language
-     * @param versionInitials
-     *            the initials of the version
-     * @param versionName
-     *            the version name
-     */
-    void addVersion(String contentType, String language, String versionInitials, String versionName);
-
-    /**
-     * the version selector widget
-     * 
-     * @return the handler to register events to
-     */
-    HasSelectionHandlers<TreeItem> getVersionSelector();
-
-    /**
-     * @return the initials of the current bible version
-     */
-    String getCurrentlySelectedVersion();
-
-    void setScriptureHolder(StepViewInterface view);
-}
\ No newline at end of file

Modified: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/widgets/HighlightableLabel.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/widgets/HighlightableLabel.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/widgets/HighlightableLabel.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -7,6 +7,19 @@
 
 public class HighlightableLabel extends InlineLabel implements HasClickAndHighlightHandlers {
 
+    public HighlightableLabel(final String text) {
+        super(text);
+    }
+
+    public HighlightableLabel() {
+        super();
+    }
+
+    /**
+     * highlights a word
+     * 
+     * @param true to highlight
+     */
     public void highlight(final boolean show) {
         if (show) {
             this.addStyleName(RESOURCES.passage().highlight());

Modified: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/PassageView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/PassageView.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/PassageView.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -1,23 +1,23 @@
 package com.tyndalehouse.step.web.client.view;
 
 import static com.tyndalehouse.step.web.client.bundles.StepResources.RESOURCES;
+import static com.tyndalehouse.step.web.client.framework.utils.StringUtils.isEmpty;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Map;
 
 import com.google.gwt.event.shared.HandlerRegistration;
 import com.google.gwt.user.client.ui.Composite;
 import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
 import com.google.gwt.user.client.ui.InlineLabel;
 import com.google.gwt.user.client.ui.Label;
 import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.VerticalPanel;
 import com.google.gwt.user.client.ui.Widget;
-import com.tyndalehouse.step.web.client.presenter.display.PassagePresenterDisplay;
+import com.tyndalehouse.step.web.client.presenter.display.PassageDisplay;
 import com.tyndalehouse.step.web.client.toolkit.handlers.OptionHandler;
 import com.tyndalehouse.step.web.client.toolkit.widgets.HighlightableLabel;
 import com.tyndalehouse.step.web.client.toolkit.widgets.OptionsButtonComposite;
-import com.tyndalehouse.step.web.client.toolkit.widgets.VerseLabel;
 import com.tyndalehouse.step.web.client.view.handlers.HasClickAndHighlightHandlers;
 import com.tyndalehouse.step.web.shared.common.ScriptureDisplayOptions;
 
@@ -30,24 +30,13 @@
  * @author CJBurrell
  * 
  */
-public class PassageView extends Composite implements PassagePresenterDisplay {
-    /**
-     * a list of VerseLabel (wrappers of bible text) that are currently being
-     * displayed and contain lemmas
-     */
-    private final List<VerseLabel> lemmaWords = new ArrayList<VerseLabel>();
-
-    /**
-     * a list of VerseLabel (wrappers of bible text) that are currently being
-     * displayed and contain morphs
-     */
-    private final List<VerseLabel> morphs = new ArrayList<VerseLabel>();
-
+public class PassageView extends Composite implements PassageDisplay {
     /** a label that does not need to be recreated each time */
     private final Label passageTitle = new Label();
     private final Panel passageHolder = new FlowPanel();
     private final Panel mainPassage = new FlowPanel();
     private final OptionsButtonComposite optionsButtonWidget = new OptionsButtonComposite();
+    private int numLines = 1;
 
     public PassageView() {
         initWidget(passageHolder);
@@ -63,25 +52,6 @@
 
     }
 
-    // /**
-    // * highlights a particular word in a passage, according to the lemmas that
-    // * are similar
-    // *
-    // * @param lemmaList
-    // * the list of lemmas to highlight in the passage
-    // */
-    // public void highlight(final List<String> lemmaList) {
-    // for (final VerseLabel vl : lemmaWords) {
-    // for (final String l : lemmaList) {
-    // if (vl.getLemma().contains(l)) {
-    // vl.setStyleName(ScriptureDisplayConstants.EMPHASISE);
-    // } else {
-    // vl.removeStyleName(ScriptureDisplayConstants.EMPHASISE);
-    // }
-    // }
-    // }
-    // }
-
     /**
      * adds an option handler to the round button containing various display
      * options
@@ -132,14 +102,57 @@
         return label;
     }
 
+    public HasClickAndHighlightHandlers createInterlinearWord(final String text, final String alternativeWording,
+            final String[] lemmas, final String[] morphs) {
+
+        final HighlightableLabel highlightableLabel = new HighlightableLabel();
+        final Label[] createdLabels = createLabel(new String[] { text, alternativeWording, concatenate(morphs),
+                concatenate(lemmas) }, new String[0], new Label[] { highlightableLabel });
+
+        return createdLabels[0] == highlightableLabel ? highlightableLabel : null;
+    }
+
+    Widget notEmpty(final String text) {
+        if (isEmpty(text)) {
+            return new HTML("&nbsp;");
+        }
+        return new Label(text);
+    }
+
     /**
+     * concatenates strings together
+     * 
+     * @param morphs
+     *            a list of elements to be concatenated
+     * @return
+     */
+    private String concatenate(final String[] attributes) {
+        final StringBuffer sb = new StringBuffer(attributes.length * 8);
+        for (final String a : attributes) {
+            sb.append(a);
+            sb.append(' ');
+        }
+        return sb.toString().trim();
+    }
+
+    /**
      * displays a title
      * 
      * @param text
      *            the text to be displayed
      */
     public void createTitle(final String text) {
-        this.createLabel(text, RESOURCES.passage().title(), new Label());
+        final Label title = new Label(text);
+        title.addStyleName(RESOURCES.passage().title());
+
+        // TODO is this a hack? not sure how to get the first line of the
+        // passage to start below the icon
+        // reassess once we move the dropdowns into the passage widget
+        if (numLines > 1) {
+            title.addStyleName(RESOURCES.passage().interlinearTitle());
+        }
+
+        mainPassage.add(title);
     }
 
     /**
@@ -167,6 +180,7 @@
     }
 
     public void createVerse() {
+
     }
 
     /**
@@ -177,15 +191,55 @@
      * @param style
      *            the style to set on the element
      * @param label
-     *            TODO
+     *            the label to use instead of creating a new one!
      * 
      */
     void createLabel(final String text, final String style, final Label label) {
-        label.setText(text);
-        label.addStyleName(style);
-        mainPassage.add(label);
+        if (numLines == 1) {
+            label.setText(text);
+            label.addStyleName(style);
+            mainPassage.add(label);
+            return;
+        }
+
+        createLabel(new String[] { text }, new String[] { style }, new Label[] { label });
     }
 
+    Label[] createLabel(final String text[], final String[] style, final Label[] label) {
+        // note this works, because the vertical panel implementation uses table
+        // layout I believe
+        final VerticalPanel interlinearWord = new VerticalPanel();
+        final Label[] addedLabels = new Label[numLines];
+
+        for (int ii = 0; ii < numLines; ii++) {
+            if (ii < text.length && !isEmpty(text[ii])) {
+
+                if (ii < label.length && label[ii] != null) {
+                    addedLabels[ii] = label[ii];
+                } else {
+                    addedLabels[ii] = new Label();
+                }
+
+                addedLabels[ii].setText(text[ii]);
+                interlinearWord.add(addedLabels[ii]);
+
+                if (ii < style.length) {
+                    addedLabels[ii].addStyleName(style[ii]);
+                }
+            } else {
+                interlinearWord.add(new HTML("&nbsp;"));
+            }
+        }
+
+        interlinearWord.addStyleName(RESOURCES.passage().interlinear());
+        mainPassage.add(interlinearWord);
+        return addedLabels;
+    }
+
+    public void setNumLines(final int numLines) {
+        this.numLines = numLines;
+    }
+
     /**
      * empties the current passage
      */

Modified: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureView.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureView.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -13,7 +13,7 @@
 import com.google.gwt.user.client.ui.TreeItem;
 import com.google.gwt.user.client.ui.Widget;
 import com.tyndalehouse.step.web.client.framework.StepViewInterface;
-import com.tyndalehouse.step.web.client.presenter.display.ScripturePresenterDisplay;
+import com.tyndalehouse.step.web.client.presenter.display.ScriptureDisplay;
 import com.tyndalehouse.step.web.client.toolkit.HasSource;
 import com.tyndalehouse.step.web.client.toolkit.widgets.BibleVersionsDropDownComposite;
 
@@ -34,7 +34,7 @@
  * @author cjburrell
  * 
  */
-public class ScriptureView extends Composite implements ScripturePresenterDisplay {
+public class ScriptureView extends Composite implements ScriptureDisplay {
     /** where the top of the scripture holder should be placed */
     private static final int SCRIPTURE_HOLDER_TOP = 20;
 

Modified: trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/client/css/passage.css
===================================================================
--- trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/client/css/passage.css	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/client/css/passage.css	2010-08-08 11:22:05 UTC (rev 171)
@@ -42,5 +42,19 @@
 }
 
 .highlight {
-	font-weight: bold;
+	text-decoration: underline;
+}
+
+.interlinear { 
+	float: left; 
+	text-align: center;
+	margin-top: 8px; 
+}
+
+.interlinear td {
+	white-space: nowrap; 
+}
+
+.interlinearTitle { 
+	height: 5em;
 }
\ No newline at end of file

Modified: trunk/step-web-server/src/main/java/com/tyndalehouse/step/web/server/handler/GetCurrentBibleTextHandler.java
===================================================================
--- trunk/step-web-server/src/main/java/com/tyndalehouse/step/web/server/handler/GetCurrentBibleTextHandler.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-server/src/main/java/com/tyndalehouse/step/web/server/handler/GetCurrentBibleTextHandler.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -2,7 +2,13 @@
 
 import static com.tyndalehouse.step.web.server.handler.util.passage.OsisParserFilter.getDefaultAttributeFilter;
 import static com.tyndalehouse.step.web.server.handler.util.passage.OsisParserFilter.getDefaultElementFilter;
-import static com.tyndalehouse.step.web.shared.scripture.PassageLanguage.resolveFromCode;
+import static com.tyndalehouse.step.web.server.service.impl.JSwordServiceImpl.STRONG_PATTERN_START;
+import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.ALTERNATIVE_WORDING;
+import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.LEMMA;
+import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.MORPH;
+import static com.tyndalehouse.step.web.shared.scripture.OsisElementType.WORD;
+import static com.tyndalehouse.step.web.shared.scripture.PassageLanguage.GREEK;
+import static com.tyndalehouse.step.web.shared.scripture.PassageLanguage.HEBREW;
 import static org.apache.commons.lang.StringUtils.isEmpty;
 import static org.apache.commons.lang.StringUtils.split;
 
@@ -33,7 +39,6 @@
 import com.tyndalehouse.step.web.shared.scripture.OsisElementType;
 import com.tyndalehouse.step.web.shared.scripture.Passage;
 import com.tyndalehouse.step.web.shared.scripture.PassageElement;
-import com.tyndalehouse.step.web.shared.scripture.PassageLanguage;
 
 /**
  * Command handler returning a portion of scripture in different formats
@@ -121,6 +126,10 @@
         if (displayOptions.containsKey(ScriptureDisplayOptions.SHOW_LEMMAS.getKey())) {
             this.attributeFilter.add(OsisElementType.LEMMA);
         }
+
+        if (displayOptions.containsKey(ScriptureDisplayOptions.REVERSE_INTERLINEAR.getKey())) {
+            this.attributeFilter.add(OsisElementType.MORPH);
+        }
     }
 
     /**
@@ -189,14 +198,15 @@
         // TODO: cope with Hebrew
         final String versionToUse;
         StrongMorphMap strongMorphMap;
+        determineOriginalLanguage(translatedText);
 
-        if (PassageLanguage.GREEK.equals(translatedText.getLanguage())) {
+        if (GREEK.equals(translatedText.getOriginalLanguage())) {
             versionToUse = DEFAULT_GREEK_INTERLINEAR_TEXT;
-        } else if (PassageLanguage.HEBREW.equals(translatedText)) {
+        } else if (HEBREW.equals(translatedText)) {
             versionToUse = DEFAULT_HEBREW_INTERLINEAR_TEXT;
         } else {
             // TODO remove all references to Action exceptions if possible
-            throw new ActionException("Unable to do reverse interlinear since base passage is neither Greek nor Hebrew");
+            throw new ActionException("Unable to do determine original language - no lemmas in text?");
         }
 
         // TODO: we need to do something different here,
@@ -224,9 +234,6 @@
         final Element osis = jsword.getOsisText(version, this.reference);
         final StrongMorphMap strongMorphMap = new StrongMorphMap();
         final Iterator<Element> it = osis.getDescendants(new Filter() {
-            /**
-             * serial id
-             */
             private static final long serialVersionUID = 4171956787222841308L;
 
             public boolean matches(final Object obj) {
@@ -262,16 +269,18 @@
      *            the map containing the links.
      */
     private void mergePassages(final Passage masterPassage, final StrongMorphMap strongMorphMap) {
-        final List<PassageElement> passageElements = masterPassage.getRootPassageNode().getChildren();
+        masterPassage.reset();
+        String[] lemma, morph;
 
-        String[] lemma, morph;
-        for (final PassageElement pe : passageElements) {
+        while (masterPassage.hasNext()) {
+            final PassageElement pe = masterPassage.next();
+
             // of interest, only the words!
-            if (OsisElementType.WORD.equals(pe.getTypeOfElement())) {
+            if (WORD.equals(pe.getTypeOfElement())) {
                 // we have several lemmas for each word, and therefore,
                 // we need to loop round them
-                lemma = split(pe.getAttribute(OsisElementType.LEMMA), LEMMA_MORPH_SEPARATOR);
-                morph = split(pe.getAttribute(OsisElementType.MORPH), LEMMA_MORPH_SEPARATOR);
+                lemma = split(pe.getAttribute(LEMMA), LEMMA_MORPH_SEPARATOR);
+                morph = split(pe.getAttribute(MORPH), LEMMA_MORPH_SEPARATOR);
 
                 final StringBuffer alternativeWording = new StringBuffer(64);
 
@@ -283,15 +292,14 @@
                 // always 0 or equal to number of lemmas
                 for (int ii = 0; ii < lemma.length; ii++) {
                     final String l = lemma[ii];
-                    final String m = ii < morph.length ? morph[ii] : null;
+                    final String m = (morph != null && ii < morph.length) ? morph[ii] : null;
                     final String text = strongMorphMap.get(l, m);
                     if (text != null) {
                         alternativeWording.append(text);
                         alternativeWording.append(' ');
                     }
-                    pe.addAttribute(OsisElementType.ALTERNATIVE_WORDING, alternativeWording.toString());
+                    pe.addAttribute(ALTERNATIVE_WORDING, alternativeWording.toString());
                 }
-
             }
         }
     }
@@ -312,11 +320,48 @@
         final List<Content> contentItems = osisFragment.getContent();
         passage.setRootPassageNode(rootPassage);
         traverseTree(contentItems, rootPassage);
-        passage.setLanguage(resolveFromCode(jsword.getLanguage(version)));
         return passage;
     }
 
+    // IMPROVEMENT: at the moment, we iterate through the whole passage,
+    // but we may not have any lemmas, so it's a waste. we could feed this down
+    // to traverse tree
+    // method and it wouldn't happen as we traverse
     /**
+     * returns H for Hebrew original text and G for Greek, or anything else!
+     */
+    void determineOriginalLanguage(final Passage passage) {
+        final String attribute = returnLemmaTag(passage);
+        if (attribute != null) {
+            passage.setOriginalLanguage(attribute.charAt(STRONG_PATTERN_START.length()) == 'H' ? HEBREW : GREEK);
+        }
+
+    }
+
+    /**
+     * iterates through a passage trying to find a Strong lemma
+     * 
+     * @param passage
+     *            passage
+     * @return the lemma if found
+     */
+    String returnLemmaTag(final Passage passage) {
+        passage.reset();
+        while (passage.hasNext()) {
+            final PassageElement nextPassageElement = passage.next();
+
+            final String attribute = nextPassageElement.getAttribute(OsisElementType.LEMMA);
+            if (attribute != null) {
+                if (attribute.startsWith(STRONG_PATTERN_START)) {
+                    return attribute;
+                }
+            }
+
+        }
+        return null;
+    }
+
+    /**
      * traverses the dom and creates passage
      * 
      * @param contentItems
@@ -369,12 +414,12 @@
             // TODO: at the moment, adding all attributes?
             final List<Attribute> attributes = element.getAttributes();
             for (final Attribute a : attributes) {
-
                 final OsisElementType forOsisType = OsisElementType.forOsisType(a.getName());
                 if (forOsisType == null || !attributeFilter.contains(forOsisType)) {
                     getLogger().debug("Attribute not returned: [" + a + "] in tag of type [" + typeOfTag + "]");
                 } else {
-                    attributeMap.put(forOsisType, a.getValue());
+                    final String attributeValue = a.getValue();
+                    attributeMap.put(forOsisType, attributeValue);
                 }
             }
 

Modified: trunk/step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture/Passage.java
===================================================================
--- trunk/step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture/Passage.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture/Passage.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -1,12 +1,13 @@
 package com.tyndalehouse.step.web.shared.scripture;
 
 import java.io.Serializable;
+import java.util.Iterator;
 import java.util.Set;
 
-public class Passage implements Serializable {
+public class Passage implements Serializable, Iterator<PassageElement> {
     private static final long serialVersionUID = -8107771273622629610L;
     private PassageElement rootPassageNode = null;
-    private PassageLanguage language = null;
+    private PassageLanguage originalLanguage = null;
     private Set<OsisElementType> elementFilter;
     private Set<OsisElementType> attributeFilter;
     private String reference;
@@ -15,16 +16,16 @@
     /**
      * @return the language
      */
-    public PassageLanguage getLanguage() {
-        return language;
+    public PassageLanguage getOriginalLanguage() {
+        return originalLanguage;
     }
 
     /**
      * @param language
      *            the language to set
      */
-    public void setLanguage(final PassageLanguage language) {
-        this.language = language;
+    public void setOriginalLanguage(final PassageLanguage language) {
+        this.originalLanguage = language;
     }
 
     /**
@@ -91,4 +92,29 @@
     public void setVersion(final String version) {
         this.version = version;
     }
+
+    public boolean hasNext() {
+        if (rootPassageNode == null) {
+            return false;
+        }
+        return rootPassageNode.hasNext();
+    }
+
+    public PassageElement next() {
+        if (rootPassageNode == null) {
+            return null;
+        }
+        return rootPassageNode.next();
+    }
+
+    /**
+     * Removes the current element from the passage, currently unsupported
+     */
+    public void remove() {
+
+    }
+
+    public void reset() {
+        rootPassageNode.reset();
+    }
 }

Modified: trunk/step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture/PassageElement.java
===================================================================
--- trunk/step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture/PassageElement.java	2010-08-01 12:56:57 UTC (rev 170)
+++ trunk/step-web-shared/src/main/java/com/tyndalehouse/step/web/shared/scripture/PassageElement.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -2,6 +2,7 @@
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -11,21 +12,38 @@
  * @author CJBurrell
  * 
  */
-public class PassageElement implements Serializable {
+public class PassageElement implements Serializable, Iterator<PassageElement> {
     private static final long serialVersionUID = 8109574278673680875L;
     private OsisElementType typeOfElement;
     private Map<OsisElementType, String> values;
     private List<PassageElement> children = null;
 
+    /**
+     * -1 indicates returned self
+     * <p>
+     * 0..n returned element 0..n
+     */
+    private int currentChild = -1;
+    private String debugId;
+
     public PassageElement(final OsisElementType typeOfElement, final Map<OsisElementType, String> attributes) {
         this.typeOfElement = typeOfElement;
         this.values = attributes;
     }
 
+    /**
+     * exposing implementation for GWT Serialisation
+     */
     public PassageElement() {
 
     }
 
+    // TODO: remove this?
+    protected PassageElement(final String debugId) {
+        this.debugId = debugId;
+
+    }
+
     /**
      * @return the typeOfElement
      */
@@ -64,7 +82,11 @@
      * @return the value corresponding to the type passed in
      */
     public String getAttribute(final OsisElementType attributeName) {
-        return values.get(attributeName);
+        if (values != null) {
+
+            return values.get(attributeName);
+        }
+        return null;
     }
 
     /**
@@ -141,4 +163,52 @@
     public void setChildren(final List<PassageElement> children) {
         this.children = children;
     }
+
+    /**
+     * returns true if another element can be found
+     */
+    public boolean hasNext() {
+        return (currentChild == -1) || (children != null && currentChild < children.size() - 1)
+                || (children != null && children.get(currentChild).hasNext());
+    }
+
+    /**
+     * @return the next element, first one's self, then one's children
+     * 
+     */
+    public PassageElement next() {
+        if (currentChild == -1) {
+            currentChild++;
+            return this;
+        }
+
+        if (!children.get(currentChild).hasNext()) {
+            currentChild++;
+        }
+
+        return children.get(currentChild).next();
+    }
+
+    /**
+     * Removes the current element from the passage, currently unsupported
+     */
+    public void remove() {
+        throw new UnsupportedOperationException("You cannot remove an element from a passage.");
+    }
+
+    public String getDebugId() {
+        return debugId;
+    }
+
+    /**
+     * resets the counters to zero to properly go through the iterator
+     */
+    public void reset() {
+        currentChild = -1;
+        if (children != null) {
+            for (final PassageElement child : children) {
+                child.reset();
+            }
+        }
+    }
 }

Added: trunk/step-web-shared/src/test/java/com/tyndalehouse/step/web/shared/scripture/PassageElementTest.java
===================================================================
--- trunk/step-web-shared/src/test/java/com/tyndalehouse/step/web/shared/scripture/PassageElementTest.java	                        (rev 0)
+++ trunk/step-web-shared/src/test/java/com/tyndalehouse/step/web/shared/scripture/PassageElementTest.java	2010-08-08 11:22:05 UTC (rev 171)
@@ -0,0 +1,58 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class PassageElementTest {
+
+    @Test
+    public void testPassageIterator() {
+        final Passage p = new Passage();
+        final PassageElement rootPassageNode = new PassageElement();
+        p.setRootPassageNode(rootPassageNode);
+
+        final PassageElement a = new PassageElement("a");
+        final PassageElement a1 = new PassageElement("a1");
+        final PassageElement a1a = new PassageElement("a1a");
+        final PassageElement a1b = new PassageElement("a1b");
+        final PassageElement a2 = new PassageElement("a2");
+        final PassageElement b = new PassageElement("b");
+        final PassageElement b1 = new PassageElement("b1");
+        final PassageElement b2 = new PassageElement("b2");
+        final PassageElement b3 = new PassageElement("b3");
+        final PassageElement c = new PassageElement("c");
+        final PassageElement d = new PassageElement("d");
+        final PassageElement d1 = new PassageElement("d1");
+        final PassageElement d1a = new PassageElement("d1a");
+        final PassageElement d1a1 = new PassageElement("d1a1");
+        final PassageElement d1a1a = new PassageElement("d1a1a");
+
+        rootPassageNode.addChildElement(a);
+        a.addChildElement(a1);
+        a1.addChildElement(a1a);
+        a1.addChildElement(a1b);
+        a.addChildElement(a2);
+        rootPassageNode.addChildElement(b);
+        b.addChildElement(b1);
+        b.addChildElement(b2);
+        b.addChildElement(b3);
+        rootPassageNode.addChildElement(c);
+        rootPassageNode.addChildElement(d);
+        d.addChildElement(d1);
+        d1.addChildElement(d1a);
+        d1a.addChildElement(d1a1);
+        d1a1.addChildElement(d1a1a);
+
+        final PassageElement[] elementOrder = new PassageElement[] { rootPassageNode, a, a1, a1a, a1b, a2, b, b1, b2,
+                b3, c, d, d1, d1a, d1a1, d1a1a };
+
+        int ii = 0;
+        while (p.hasNext()) {
+            final PassageElement nextPassageElement = p.next();
+
+            assertEquals("Got [" + nextPassageElement.getDebugId() + "] instead of [" + elementOrder[ii].getDebugId()
+                    + "]", elementOrder[ii++], nextPassageElement);
+        }
+    }
+}




More information about the Tynstep-svn mailing list