[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(" ");
+ }
+ 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(" "));
+ }
+ }
+
+ 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