[Tynstep-svn] r195 - in trunk/step: step-core step-core/src/main/java/com/tyndalehouse/step/core step-core/src/main/java/com/tyndalehouse/step/core/exceptions step-core/src/main/java/com/tyndalehouse/step/core/guice step-core/src/main/java/com/tyndalehouse/step/core/guice/providers step-core/src/main/java/com/tyndalehouse/step/core/models step-core/src/main/java/com/tyndalehouse/step/core/service step-core/src/main/java/com/tyndalehouse/step/core/service/impl step-core/src/main/java/com/tyndalehouse/step/core/utils step-core/src/main/java/com/tyndalehouse/step/core/xsl step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl step-core/src/main/resources step-core/src/main/resources/com/tyndalehouse/step/core step-core/src/main/resources/com/tyndalehouse/step/core/service/impl step-core/src/test/java/com/tyndalehouse/step/core/service step-core/src/test/java/com/tyndalehouse/step/core/service/impl step-core/src/test/java/com/tyndalehouse/step/core/utils step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl step-parent step-server step-server/src/main/java/com/tyndalehouse/step/server step-web step-web/src step-web/src/main/java/com/tyndalehouse/step step-web/src/main/java/com/tyndalehouse/step/guice step-web/src/main/java/com/tyndalehouse/step/rest step-web/src/main/java/com/tyndalehouse/step/rest/controllers step-web/src/main/java/com/tyndalehouse/step/rest/framework step-web/src/main/java/com/tyndalehouse/step/rest/wrappers step-web/src/main/webapp step-web/src/main/webapp/WEB-INF step-web/src/main/webapp/css step-web/src/main/webapp/js step-web/src/test step-web/src/test/java step-web/src/test/java/com step-web/src/test/java/com/tyndalehouse step-web/src/test/java/com/tyndalehouse/step step-web/src/test/java/com/tyndalehouse/step/rest step-web/src/test/java/com/tyndalehouse/step/rest/controllers
ChrisBurrell at crosswire.org
ChrisBurrell at crosswire.org
Sun Dec 19 04:27:36 MST 2010
Author: ChrisBurrell
Date: 2010-12-19 04:27:36 -0700 (Sun, 19 Dec 2010)
New Revision: 195
Added:
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultInstallersProvider.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultLexiconRefsProvider.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultVersionsProvider.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/JSwordUtils.java
trunk/step/step-core/src/main/resources/step.core.properties
trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/
trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/StepServletConfig.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/SetupController.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/TimelineController.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/Cached.java
trunk/step/step-web/src/main/webapp/css/setup-layout.css
trunk/step/step-web/src/main/webapp/js/setup.js
trunk/step/step-web/src/main/webapp/setup.jsp
trunk/step/step-web/src/test/
trunk/step/step-web/src/test/java/
trunk/step/step-web/src/test/java/com/
trunk/step/step-web/src/test/java/com/tyndalehouse/
trunk/step/step-web/src/test/java/com/tyndalehouse/step/
trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/
trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/
trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java
Removed:
trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/config/
trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/service/impl/old_default.xsl
trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/service/impl/old_interlinear.xsl
Modified:
trunk/step/step-core/pom.xml
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/StepInternalException.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/BibleVersion.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/Definition.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/LookupOption.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BibleInformationService.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/JSwordService.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/ModuleService.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BibleInformationServiceImpl.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/ModuleServiceImpl.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/XslHelper.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/InterlinearProvider.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/MultiInterlinearProvider.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/XslConversionType.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/DualKey.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImpl.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/MultiInterlinearProviderImpl.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/ModuleServiceImplTest.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/utils/StringConversionUtilsTest.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImplTest.java
trunk/step/step-parent/pom.xml
trunk/step/step-server/pom.xml
trunk/step/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java
trunk/step/step-web/pom.xml
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/JsonExceptionResolver.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BibleController.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/ModuleController.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/wrappers/HtmlWrapper.java
trunk/step/step-web/src/main/webapp/WEB-INF/web.xml
trunk/step/step-web/src/main/webapp/index.jsp
trunk/step/step-web/src/main/webapp/js/bookmark.js
trunk/step/step-web/src/main/webapp/js/init.js
trunk/step/step-web/src/main/webapp/js/lexicon_definition.js
trunk/step/step-web/src/main/webapp/js/passage.js
trunk/step/step-web/src/main/webapp/js/passage_toolbar.js
trunk/step/step-web/src/main/webapp/js/ui_hooks.js
Log:
Modified: trunk/step/step-core/pom.xml
===================================================================
--- trunk/step/step-core/pom.xml 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/pom.xml 2010-12-19 11:27:36 UTC (rev 195)
@@ -23,11 +23,6 @@
</dependency>
<dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- </dependency>
-
- <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
@@ -41,7 +36,12 @@
<groupId>org.crosswire</groupId>
<artifactId>jsword</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.jdom</groupId>
+ <artifactId>jdom</artifactId>
+ </dependency>
+
<!-- common utils -->
<dependency>
<groupId>commons-beanutils</groupId>
@@ -53,6 +53,14 @@
<artifactId>commons-lang</artifactId>
</dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.jolira</groupId>
+ <artifactId>guice</artifactId>
+ </dependency>
</dependencies>
</project>
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/StepInternalException.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/StepInternalException.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/StepInternalException.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,5 +1,12 @@
package com.tyndalehouse.step.core.exceptions;
+/**
+ * The default exception to be thrown throughout the application. It is of type {@link RuntimeException} so that it does
+ * not require explicit catching
+ *
+ * @author Chris
+ *
+ */
public class StepInternalException extends RuntimeException {
private static final long serialVersionUID = -5636677138385910988L;
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,68 @@
+package com.tyndalehouse.step.core.guice;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.crosswire.jsword.book.install.Installer;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Module;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+import com.tyndalehouse.step.core.guice.providers.DefaultInstallersProvider;
+import com.tyndalehouse.step.core.guice.providers.DefaultLexiconRefsProvider;
+import com.tyndalehouse.step.core.guice.providers.DefaultVersionsProvider;
+import com.tyndalehouse.step.core.service.BibleInformationService;
+import com.tyndalehouse.step.core.service.JSwordService;
+import com.tyndalehouse.step.core.service.ModuleService;
+import com.tyndalehouse.step.core.service.impl.BibleInformationServiceImpl;
+import com.tyndalehouse.step.core.service.impl.JSwordServiceImpl;
+import com.tyndalehouse.step.core.service.impl.ModuleServiceImpl;
+
+/**
+ * The module configuration that configures the application via guice
+ *
+ * @author Chris
+ *
+ */
+public class StepCoreModule extends AbstractModule implements Module {
+ private static final String CORE_GUICE_PROPERTIES = "/step.core.properties";
+
+ @Override
+ protected void configure() {
+ bind(Properties.class).annotatedWith(Names.named("StepCoreProperties")).toInstance(readProperties());
+
+ bind(JSwordService.class).to(JSwordServiceImpl.class).asEagerSingleton();
+ bind(BibleInformationService.class).to(BibleInformationServiceImpl.class).asEagerSingleton();
+ bind(ModuleService.class).to(ModuleServiceImpl.class).asEagerSingleton();
+
+ bind(new TypeLiteral<List<String>>() {
+ }).annotatedWith(Names.named("defaultVersions")).toProvider(DefaultVersionsProvider.class);
+ bind(new TypeLiteral<Map<String, String>>() {
+ }).annotatedWith(Names.named("defaultLexiconRefs")).toProvider(DefaultLexiconRefsProvider.class);
+ bind(new TypeLiteral<List<Installer>>() {
+ }).toProvider(DefaultInstallersProvider.class);
+ }
+
+ /**
+ * reads the core properties from the file
+ *
+ * @return a list of properties read from file
+ */
+ private Properties readProperties() {
+ final InputStream stream = getClass().getResourceAsStream(CORE_GUICE_PROPERTIES);
+ final Properties appProperties = new Properties();
+ try {
+ appProperties.load(stream);
+ Names.bindProperties(super.binder(), appProperties);
+ } catch (final IOException e) {
+ // This is the preferred way to tell Guice something went wrong
+ super.addError(e);
+ }
+ return appProperties;
+ }
+
+}
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultInstallersProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultInstallersProvider.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultInstallersProvider.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,73 @@
+package com.tyndalehouse.step.core.guice.providers;
+
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.crosswire.jsword.book.install.Installer;
+import org.crosswire.jsword.book.install.sword.HttpSwordInstaller;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
+import com.tyndalehouse.step.core.exceptions.StepInternalException;
+
+/**
+ * Provides a set of installers for installing Bibles, modules, etc e.g. from Crosswire
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class DefaultInstallersProvider implements Provider<List<Installer>> {
+ private final List<Installer> installers;
+
+ /**
+ * @param stepProperties the properties for the whole STEP application
+ * @param proxyHost the host name of the proxy
+ * @param proxyPort the port of a proxy to go through
+ */
+ @Inject
+ public DefaultInstallersProvider(@Named("StepCoreProperties") final Properties stepProperties,
+ @Named("app.proxy.host") final String proxyHost, @Named("app.proxy.port") final String proxyPort) {
+ this.installers = new ArrayList<Installer>();
+ final Set<Entry<Object, Object>> entrySet = stepProperties.entrySet();
+ for (final Entry<Object, Object> entry : entrySet) {
+ if (entry.getKey() instanceof String && ((String) entry.getKey()).startsWith("installer")) {
+ // add to list
+ final String[] split = StringUtils.split(entry.getValue().toString(), ",");
+
+ final HttpSwordInstaller installer = new HttpSwordInstaller();
+ installer.setHost(split[0]);
+ installer.setPackageDirectory(split[1]);
+ installer.setCatalogDirectory(split[2]);
+
+ if (isNotBlank(proxyHost)) {
+ installer.setProxyHost(proxyHost);
+ }
+
+ if (isNotBlank(proxyPort)) {
+ try {
+ final Integer p = Integer.parseInt(proxyPort);
+ installer.setProxyPort(p.intValue());
+ } catch (final NumberFormatException e) {
+ throw new StepInternalException("Unable to parse port number " + proxyPort, e);
+ }
+ }
+
+ this.installers.add(installer);
+ }
+ }
+ }
+
+ @Override
+ public List<Installer> get() {
+ return this.installers;
+ }
+}
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultLexiconRefsProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultLexiconRefsProvider.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultLexiconRefsProvider.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,31 @@
+package com.tyndalehouse.step.core.guice.providers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.inject.Provider;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+
+/**
+ * Provides the mappings between lexicon key references and the module initials that should be used.
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class DefaultLexiconRefsProvider implements Provider<Map<String, String>> {
+
+ /**
+ * @return the list of default versions to be installed on a STEP installation
+ *
+ */
+ @Provides
+ public Map<String, String> get() {
+ final Map<String, String> moduleRefs = new HashMap<String, String>();
+ moduleRefs.put("strong:H", "StrongsHebrew");
+ moduleRefs.put("strong:G", "StrongsGreek");
+ moduleRefs.put("robinson:", "Robinson");
+ return moduleRefs;
+ }
+}
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultVersionsProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultVersionsProvider.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultVersionsProvider.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,33 @@
+package com.tyndalehouse.step.core.guice.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.inject.Provider;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+
+/**
+ * Provides a list of default versions that should be installed for the application
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class DefaultVersionsProvider implements Provider<List<String>> {
+
+ /**
+ * @return the list of default versions to be installed on a STEP installation
+ *
+ */
+ @Provides
+ public List<String> get() {
+ final List<String> versions = new ArrayList<String>();
+ versions.add("ESV");
+ versions.add("KJV");
+ versions.add("StrongsHebrew");
+ versions.add("StrongsGreek");
+ versions.add("Byz");
+ return versions;
+ }
+}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/BibleVersion.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/BibleVersion.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/BibleVersion.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -15,10 +15,16 @@
private String language;
private boolean hasStrongs;
+ /**
+ * @return true if the version contains strong-tagged information
+ */
public boolean isHasStrongs() {
return this.hasStrongs;
}
+ /**
+ * @param hasStrongs true if the version contains strong information
+ */
public void setHasStrongs(final boolean hasStrongs) {
this.hasStrongs = hasStrongs;
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/Definition.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/Definition.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/Definition.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -9,6 +9,12 @@
private final String key;
private final String explanation;
+ /**
+ * A definition is made up of a key and an explanation
+ *
+ * @param key a key identifying where the definition came from
+ * @param explanation an explanation
+ */
public Definition(final String key, final String explanation) {
this.key = key;
this.explanation = explanation;
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/LookupOption.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/LookupOption.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/LookupOption.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -11,10 +11,12 @@
*
*/
public enum LookupOption {
+ // CHECKSTYLE:OFF TODO change the values in the XSL file
/**
* Showing headings
*/
HEADINGS("Headings", "Headings", XslConversionType.DEFAULT, true),
+ // CHECKSTYLE:ON
/**
* Showing headings
*/
@@ -24,11 +26,12 @@
/** Morphology */
MORPHOLOGY("Morph", "Morphology", XslConversionType.INTERLINEAR),
+ // CHECKSTYLE:OFF
/**
* Interlinears are available when Strongs are available.
*/
INTERLINEAR("Interlinear", "Interlinear", XslConversionType.INTERLINEAR),
-
+ // CHECKSTYLE:ON
/**
* Showing headings
*/
@@ -61,7 +64,8 @@
* @param stylesheet the stylesheet to use
* @param displayName the name to display on the user interface
*/
- private LookupOption(final String xsltParameterName, final String displayName, final XslConversionType stylesheet) {
+ private LookupOption(final String xsltParameterName, final String displayName,
+ final XslConversionType stylesheet) {
this(xsltParameterName, displayName, stylesheet, false);
}
@@ -71,8 +75,8 @@
* @param displayName the name to display on the user interface
* @param enabledByDefault true to have the UI display the option by default
*/
- private LookupOption(final String xsltParameterName, final String displayName, final XslConversionType stylesheet,
- final boolean enabledByDefault) {
+ private LookupOption(final String xsltParameterName, final String displayName,
+ final XslConversionType stylesheet, final boolean enabledByDefault) {
this.xsltParameterName = xsltParameterName;
this.displayName = displayName;
this.stylesheet = stylesheet;
@@ -86,10 +90,16 @@
return this.xsltParameterName;
}
+ /**
+ * @return the display name of the lookup option
+ */
public String getDisplayName() {
return this.displayName;
}
+ /**
+ * @return the stylesheet that should be used
+ */
public XslConversionType getStylesheet() {
return this.stylesheet;
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BibleInformationService.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BibleInformationService.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BibleInformationService.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -7,8 +7,8 @@
import com.tyndalehouse.step.core.models.LookupOption;
/**
- * Interface to the service that gives information about the books of the bible, the different types of bible, etc. This
- * service will mainly use JSword but may also rely on other data sources to display text.
+ * Interface to the service that gives information about the books of the bible, the different types of bible,
+ * etc. This service will mainly use JSword but may also rely on other data sources to display text.
*
* @author Chris
*
@@ -16,15 +16,15 @@
public interface BibleInformationService {
/**
- * Queries Jsword to return all the available versions of the bible
+ * Queries Jsword to return all the installed versions of the bible
*
* @return all the available versions of the bible
*/
- List<BibleVersion> getBibleVersions();
+ List<BibleVersion> getAvailableBibleVersions();
/**
- * This method selects passage text and forms XML for the client. This is done server side so that the client does
- * not need to render each div individually.
+ * This method selects passage text and forms XML for the client. This is done server side so that the
+ * client does not need to render each div individually.
*
* @param version the initials that identify the bible version
* @param reference the reference
@@ -32,7 +32,8 @@
* @param interlinearVersion version to use as the interlinear
* @return the HTML string passed back for consumption
*/
- String getPassageText(String version, String reference, List<LookupOption> lookupOptions, String interlinearVersion);
+ String getPassageText(String version, String reference, List<LookupOption> lookupOptions,
+ String interlinearVersion);
/**
*
@@ -44,8 +45,26 @@
/**
* Gets a list of all supported features so far
*
- * @return
+ * @return the list of lookup options available to the user
*/
List<EnrichedLookupOption> getAllFeatures();
+ /**
+ * Checks a set of core versions to see if they have been installed
+ *
+ * @return true if the core modules have been installed
+ */
+ boolean hasCoreModules();
+
+ /**
+ * installs the default modules (such as KJV, ESV, Strongs, Robinson)
+ */
+ void installDefaultModules();
+
+ /**
+ * installs separate modules
+ *
+ * @param reference the reference, initials or book name
+ */
+ void installModules(String reference);
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/JSwordService.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/JSwordService.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/JSwordService.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -7,6 +7,12 @@
import com.tyndalehouse.step.core.models.LookupOption;
+/**
+ * The service providing access to JSword. All JSword calls should preferably be placed in this service
+ *
+ * @author Chris
+ *
+ */
public interface JSwordService {
/**
* returns the Osis Text as a String
@@ -31,10 +37,10 @@
/**
* looks up any installed module
*
- * @param bibleCategory the category of the bible to lookup
+ * @param bibleCategory the categories of the modules to be returned
* @return a list of bible books
*/
- List<Book> getModules(BookCategory bibleCategory);
+ List<Book> getInstalledModules(BookCategory... bibleCategory);
/**
* Gets the features for a module
@@ -44,4 +50,35 @@
*/
List<LookupOption> getFeatures(String version);
+ /**
+ * Using module initials, checks whether the module has been installed
+ *
+ * @param moduleInitials the initials of the modules to check for installation state
+ * @return true if the module is installed
+ */
+ boolean isInstalled(String moduleInitials);
+
+ /**
+ * Kicks of a process to install this version (asynchronous)
+ *
+ * @param version version to be installs
+ */
+ void installBook(String version);
+
+ /**
+ * assesses the progress made on an installation
+ *
+ * @param bookName the book name
+ * @return the percentage of completion (0 - 1.0)
+ */
+ double getProgressOnInstallation(String bookName);
+
+ /**
+ * retrieves all modules that have been installed
+ *
+ * @param bookCategory the list of categories to be included
+ * @return all modules whether installed or not
+ */
+ List<Book> getAllModules(BookCategory... bookCategory);
+
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/ModuleService.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/ModuleService.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/ModuleService.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -2,6 +2,7 @@
import java.util.List;
+import com.tyndalehouse.step.core.models.BibleVersion;
import com.tyndalehouse.step.core.models.Definition;
/**
@@ -27,4 +28,14 @@
* @return the definitions associated with the references
*/
Definition getDefinition(String reference);
+
+ /**
+ * @return all installed modules
+ */
+ List<BibleVersion> getAvailableModules();
+
+ /**
+ * @return a list of all modules that could be installed
+ */
+ List<BibleVersion> getAllInstallableModules();
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BibleInformationServiceImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BibleInformationServiceImpl.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BibleInformationServiceImpl.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -2,18 +2,19 @@
import static com.tyndalehouse.step.core.models.LookupOption.INTERLINEAR;
import static com.tyndalehouse.step.core.models.LookupOption.STRONG_NUMBERS;
+import static com.tyndalehouse.step.core.utils.JSwordUtils.getSortedSerialisableList;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import java.util.ArrayList;
import java.util.List;
-import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.BookCategory;
-import org.crosswire.jsword.book.FeatureType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
import com.tyndalehouse.step.core.models.BibleVersion;
import com.tyndalehouse.step.core.models.EnrichedLookupOption;
import com.tyndalehouse.step.core.models.LookupOption;
@@ -25,37 +26,38 @@
*
* @author CJBurrell
*/
+ at Singleton
public class BibleInformationServiceImpl implements BibleInformationService {
- private final Logger logger = LoggerFactory.getLogger(getClass());
+ private static final Logger LOGGER = LoggerFactory.getLogger(BibleInformationServiceImpl.class);
+ private final List<String> defaultVersions;
+ private final JSwordService jsword;
- @Autowired
- private JSwordService jsword;
+ /**
+ * The bible information service, retrieving content and meta data
+ *
+ * @param defaultVersions a list of the default versions that should be installed
+ * @param jsword the jsword service
+ */
+ @Inject
+ public BibleInformationServiceImpl(@Named("defaultVersions") final List<String> defaultVersions,
+ final JSwordService jsword) {
+ this.jsword = jsword;
+ this.defaultVersions = defaultVersions;
+ }
- public List<BibleVersion> getBibleVersions() {
- this.logger.info("Getting bible versions");
- final List<Book> bibles = this.jsword.getModules(BookCategory.BIBLE);
-
- final List<BibleVersion> versions = new ArrayList<BibleVersion>();
-
- // we only send back what we need
- for (final Book b : bibles) {
- final BibleVersion v = new BibleVersion();
- v.setName(b.getName());
- v.setInitials(b.getInitials());
- v.setLanguage(b.getLanguage().getName());
- v.setHasStrongs(b.hasFeature(FeatureType.STRONGS_NUMBERS));
- versions.add(v);
- }
-
- this.logger.debug("Returning {} versions", bibles.size());
- return versions;
+ @Override
+ public List<BibleVersion> getAvailableBibleVersions() {
+ LOGGER.info("Getting bible versions");
+ return getSortedSerialisableList(this.jsword.getInstalledModules(BookCategory.BIBLE));
}
+ @Override
public String getPassageText(final String version, final String reference, final List<LookupOption> options,
final String interlinearVersion) {
return this.jsword.getOsisText(version, reference, options, interlinearVersion);
}
+ @Override
public List<EnrichedLookupOption> getAllFeatures() {
final LookupOption[] lo = LookupOption.values();
final List<EnrichedLookupOption> elo = new ArrayList<EnrichedLookupOption>(lo.length + 1);
@@ -70,6 +72,7 @@
return elo;
}
+ @Override
public List<LookupOption> getFeaturesForVersion(final String version) {
final List<LookupOption> features = this.jsword.getFeatures(version);
if (features.contains(STRONG_NUMBERS)) {
@@ -77,4 +80,27 @@
}
return features;
}
+
+ @Override
+ public boolean hasCoreModules() {
+ for (final String version : this.defaultVersions) {
+ if (!this.jsword.isInstalled(version)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void installDefaultModules() {
+ // we install the module for every core module in the list
+ for (final String book : this.defaultVersions) {
+ this.jsword.installBook(book);
+ }
+ }
+
+ @Override
+ public void installModules(final String reference) {
+ this.jsword.installBook(reference);
+ }
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,6 +1,7 @@
package com.tyndalehouse.step.core.service.impl;
import static com.tyndalehouse.step.core.xsl.XslConversionType.DEFAULT;
+import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.crosswire.jsword.book.BookCategory.BIBLE;
@@ -13,6 +14,8 @@
import javax.xml.transform.TransformerException;
+import org.crosswire.common.progress.JobManager;
+import org.crosswire.common.progress.Progress;
import org.crosswire.common.xml.Converter;
import org.crosswire.common.xml.SAXEventProvider;
import org.crosswire.common.xml.TransformingSAXEventProvider;
@@ -24,11 +27,15 @@
import org.crosswire.jsword.book.BookFilter;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.FeatureType;
+import org.crosswire.jsword.book.install.InstallException;
+import org.crosswire.jsword.book.install.Installer;
import org.crosswire.jsword.passage.NoSuchKeyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
import com.tyndalehouse.step.core.exceptions.StepInternalException;
import com.tyndalehouse.step.core.models.LookupOption;
import com.tyndalehouse.step.core.service.JSwordService;
@@ -40,32 +47,75 @@
* @author CJBurrell
*
*/
+ at Singleton
public class JSwordServiceImpl implements JSwordService {
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private static final Logger LOGGER = LoggerFactory.getLogger(JSwordServiceImpl.class);
+ private final List<Installer> bookInstallers;
+ /**
+ * constructs the jsword service.
+ *
+ * @param installers the installers are the objects that query the crosswire servers
+ */
+ @Inject
+ public JSwordServiceImpl(final List<Installer> installers) {
+ this.bookInstallers = installers;
+ }
+
+ /**
+ * @param bibleCategory the categories of books that should be considered
+ * @return returns a list of installed modules
+ */
@SuppressWarnings("unchecked")
- public List<Book> getModules(final BookCategory bibleCategory) {
- if (bibleCategory == null) {
+ public List<Book> getInstalledModules(final BookCategory... bibleCategory) {
+ if (bibleCategory == null || bibleCategory.length == 0) {
return new ArrayList<Book>();
}
+ // quickly transform the categories to a set for fast comparison
+ final Set<BookCategory> categories = new HashSet<BookCategory>();
+ for (int ii = 0; ii < bibleCategory.length; ii++) {
+ categories.add(bibleCategory[ii]);
+ }
+
// we set up a filter to retrieve just certain types of books
final BookFilter bf = new BookFilter() {
public boolean test(final Book b) {
- return bibleCategory.equals(b.getBookCategory());
+ return categories.contains(b.getBookCategory());
}
};
return Books.installed().getBooks(bf);
}
+ /**
+ * @param bibleCategory the list of books that should be considered
+ * @return a list of all modules
+ */
+ @SuppressWarnings("unchecked")
+ public List<Book> getAllModules(final BookCategory... bibleCategory) {
+ final List<Book> books = new ArrayList<Book>();
+ for (final Installer installer : this.bookInstallers) {
+ try {
+ installer.reloadBookList();
+ books.addAll(installer.getBooks());
+ } catch (final InstallException e) {
+ // log an error
+ LOGGER.error("Unable to update installer", e);
+ }
+ }
+ return books;
+ }
+
+ @Override
public String getOsisText(final String version, final String reference) {
final List<LookupOption> options = new ArrayList<LookupOption>();
return getOsisText(version, reference, options, null);
}
+ @Override
public String getOsisText(final String version, final String reference, final List<LookupOption> options,
final String interlinearVersion) {
- this.logger.debug("Retrieving text for ({}, {})", version, reference);
+ LOGGER.debug("Retrieving text for ({}, {})", version, reference);
try {
final Book currentBook = Books.installed().getBook(version);
@@ -81,13 +131,12 @@
// for now, we just assume that we'll only have one option, but this may change later
// TODO, we can probably cache the resource
final TransformingSAXEventProvider tsep = new TransformingSAXEventProvider(getClass()
- .getResource(requiredTransformation.iterator().next().getFile()).toURI(), osissep);
+ .getResource(requiredTransformation.iterator().next().getFile()).toURI(),
+ osissep);
// set parameters here
setOptions(tsep, options, version, reference);
setupInterlinearOptions(tsep, interlinearVersion, reference);
-
- // then return
return tsep;
} catch (final URISyntaxException e) {
throw new StepInternalException("Failed to load resource correctly", e);
@@ -97,10 +146,10 @@
}.convert(osissep);
return XMLUtil.writeToString(htmlsep);
} catch (final NoSuchKeyException e) {
- throw new StepInternalException("The verse specified was not found: [" + reference + "]", e);
+ throw new StepInternalException("The verse specified was not found: " + reference, e);
} catch (final BookException e) {
- throw new StepInternalException("Unable to query the book data to retrieve specified passage [" + version
- + "] [" + reference + "]", e);
+ throw new StepInternalException("Unable to query the book data to retrieve specified passage: "
+ + version + ", " + reference, e);
} catch (final SAXException e) {
throw new StepInternalException(e.getMessage(), e);
} catch (final TransformerException e) {
@@ -131,6 +180,7 @@
return chosenOptions;
}
+ @Override
public List<LookupOption> getFeatures(final String version) {
// obtain the book
final Book book = Books.installed().getBook(version);
@@ -144,26 +194,29 @@
// cycle through each option
for (final LookupOption lo : LookupOption.values()) {
final FeatureType ft = FeatureType.fromString(lo.getXsltParameterName());
- if (ft != null && isNotEmpty(lo.getDisplayName())) {
- if (book.getBookMetaData().hasFeature(ft)) {
- options.add(lo);
- }
+ if (ft != null && isNotEmpty(lo.getDisplayName()) && book.getBookMetaData().hasFeature(ft)) {
+ options.add(lo);
}
}
return options;
}
- private void setupInterlinearOptions(final TransformingSAXEventProvider tsep, final String interlinearVersion,
- final String reference) {
+ /**
+ * sets up the default interlinear options
+ *
+ * @param tsep the transformer that we want to set up
+ * @param interlinearVersion the interlinear version(s) that the users have requested
+ * @param reference the reference the user is interested in
+ */
+ private void setupInterlinearOptions(final TransformingSAXEventProvider tsep,
+ final String interlinearVersion, final String reference) {
if (tsep.getParameter(LookupOption.INTERLINEAR.getXsltParameterName()) != null) {
tsep.setParameter("interlinearReference", reference);
if (isNotBlank(interlinearVersion)) {
tsep.setParameter("interlinearVersion", interlinearVersion);
- } else {
- // depending on OT or NT, we select a default interlinear version
-
}
+ // TODO else depending on OT or NT, we select a default interlinear version
}
}
@@ -174,7 +227,6 @@
* @param options the options available
* @param version the version to initialise a potential interlinear with
* @param textScope the scope of the text to lookup
- * @return the XSLT that will give me the correct transformation
*/
protected void setOptions(final TransformingSAXEventProvider tsep, final List<LookupOption> options,
final String version, final String textScope) {
@@ -187,4 +239,81 @@
}
}
+ @Override
+ public boolean isInstalled(final String moduleInitials) {
+ return Books.installed().getBook(moduleInitials) != null;
+ }
+
+ @Override
+ public void installBook(final String initials) {
+ LOGGER.debug("Installing module [{}]", initials);
+
+ if (isBlank(initials)) {
+ throw new StepInternalException("No version was found");
+ }
+
+ // check if already installed?
+ if (!isInstalled(initials)) {
+ LOGGER.debug("Book was not already installed, so kicking off installation process [{}]");
+ for (final Installer i : this.bookInstallers) {
+ final Book bookToBeInstalled = i.getBook(initials);
+
+ if (bookToBeInstalled != null) {
+ // then we can kick off installation and return
+ try {
+ i.install(bookToBeInstalled);
+ } catch (final InstallException e) {
+ // we log error here,
+ LOGGER.error(
+ "An error occurred error, and we unable to use this installer for module"
+ + initials, e);
+
+ // but go round the loop to see if more options are available
+ continue;
+ }
+ return;
+ }
+ }
+ // if we get here, then we were unable to install the book
+ // since we couldn't find it.
+ throw new StepInternalException("Unable to find book with initials " + initials);
+ }
+
+ // if we get here then we had already installed the book - how come we're asking for this again?
+ LOGGER.warn("A request to install an already installed book was made for initials " + initials);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public double getProgressOnInstallation(final String bookName) {
+ if (isBlank(bookName)) {
+ throw new StepInternalException("The book name provided was blank");
+ }
+
+ if (isInstalled(bookName)) {
+ return 1;
+ }
+
+ final Set<Progress> jswordJobs = JobManager.getJobs();
+ // not yet installed (or at least wasn't on the lines above, so check job list
+ for (final Progress p : jswordJobs) {
+ final String expectedJobName = "Installing book: " + bookName;
+ if (expectedJobName.equals(p.getJobName())) {
+ if (p.isFinished()) {
+ return 1;
+ }
+
+ return (double) p.getWork() / p.getTotalWork();
+ }
+ }
+
+ // the job may have completed by now, while we did the search, so do a final check
+ if (isInstalled(bookName)) {
+ return 1;
+ }
+
+ throw new StepInternalException(
+ "An unknown error has occurred: the job has disappeared of the job list, "
+ + "but the module is not installed");
+ }
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/ModuleServiceImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/ModuleServiceImpl.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/ModuleServiceImpl.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,5 +1,7 @@
package com.tyndalehouse.step.core.service.impl;
+import static com.tyndalehouse.step.core.utils.JSwordUtils.getSortedSerialisableList;
+import static org.apache.commons.collections.CollectionUtils.subtract;
import static org.apache.commons.lang.StringUtils.split;
import java.util.ArrayList;
@@ -7,11 +9,16 @@
import java.util.Map;
import java.util.Map.Entry;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.BookCategory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
import com.tyndalehouse.step.core.exceptions.StepInternalException;
+import com.tyndalehouse.step.core.models.BibleVersion;
import com.tyndalehouse.step.core.models.Definition;
import com.tyndalehouse.step.core.service.JSwordService;
import com.tyndalehouse.step.core.service.ModuleService;
@@ -23,13 +30,26 @@
* @author Chris Burrell
*
*/
+ at Singleton
public class ModuleServiceImpl implements ModuleService {
- private final Logger logger = LoggerFactory.getLogger(getClass());
- private Map<String, String> defaultModuleLexicons;
+ private static final Logger LOGGER = LoggerFactory.getLogger(ModuleServiceImpl.class);
+ private final Map<String, String> defaultLexiconsRefs;
+ private final JSwordService jsword;
- @Autowired
- private JSwordService jsword;
+ /**
+ * constructs a service to give module information and content
+ *
+ * @param lexiconRefs the default references that should be used
+ * @param jsword the jsword service to retrieve data
+ */
+ @Inject
+ public ModuleServiceImpl(@Named("defaultLexiconRefs") final Map<String, String> lexiconRefs,
+ final JSwordService jsword) {
+ this.defaultLexiconsRefs = lexiconRefs;
+ this.jsword = jsword;
+ }
+ @Override
public Definition getDefinition(final String reference) {
final String lookupModule = getLookupModule(reference);
if (lookupModule != null) {
@@ -37,10 +57,11 @@
StringConversionUtils.getAnyKey(reference, false)));
}
- this.logger.warn("No module could be found for [{}]", reference);
+ LOGGER.warn("No module could be found for [{}]", reference);
return null;
}
+ @Override
public List<Definition> getDefinitions(final String references) {
// first we split the definitions in separate parts
final String[] refs = split(references);
@@ -51,7 +72,7 @@
final List<Definition> defs = new ArrayList<Definition>();
for (final String r : refs) {
- this.logger.debug("Looking up {}", r);
+ LOGGER.debug("Looking up {}", r);
final Definition definition = getDefinition(r);
if (definition != null) {
defs.add(definition);
@@ -62,14 +83,13 @@
}
/**
- * TODO: later we can drive this with a dropdown on the UI Based on the reference provided, we determine the correct
- * module to lookup
+ * Returns the module that should be used to lookup a reference
*
* @param reference the reference to base the lookup option on
* @return the initials of the module to lookup
*/
String getLookupModule(final String reference) {
- for (final Entry<String, String> e : this.defaultModuleLexicons.entrySet()) {
+ for (final Entry<String, String> e : this.defaultLexiconsRefs.entrySet()) {
if (reference.startsWith(e.getKey())) {
return e.getValue();
}
@@ -77,11 +97,21 @@
return null;
}
- /**
- * @param defaultModuleLexicons the defaultModuleLexicons to set
- */
- public void setDefaultModuleLexicons(final Map<String, String> defaultModuleLexicons) {
- this.defaultModuleLexicons = defaultModuleLexicons;
+ @Override
+ public List<BibleVersion> getAvailableModules() {
+ LOGGER.info("Getting bible versions");
+ return getSortedSerialisableList(this.jsword.getInstalledModules(BookCategory.BIBLE, BookCategory.DICTIONARY,
+ BookCategory.COMMENTARY));
}
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<BibleVersion> getAllInstallableModules() {
+ LOGGER.info("Returning all modules currently not installed");
+ final List<BibleVersion> installedVersions = getAvailableModules();
+ final List<Book> allModules = this.jsword.getAllModules(BookCategory.BIBLE, BookCategory.DICTIONARY,
+ BookCategory.COMMENTARY);
+
+ return getSortedSerialisableList(subtract(allModules, installedVersions));
+ }
}
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/JSwordUtils.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/JSwordUtils.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/JSwordUtils.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,63 @@
+package com.tyndalehouse.step.core.utils;
+
+import static java.util.Collections.sort;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+
+import org.crosswire.common.util.Language;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.FeatureType;
+
+import com.tyndalehouse.step.core.models.BibleVersion;
+
+/**
+ * a set of utility methods to manipulate the JSword objects coming out
+ *
+ * @author Chris
+ *
+ */
+public final class JSwordUtils {
+ /**
+ * hiding implementaiton
+ */
+ private JSwordUtils() {
+ // no implementation
+ }
+
+ /**
+ * returns a sorted list from another list, with only the required information
+ *
+ * @param bibles a list of jsword bibles
+ * @return the list of bibles
+ */
+ public static List<BibleVersion> getSortedSerialisableList(final Collection<Book> bibles) {
+ final List<BibleVersion> versions = new ArrayList<BibleVersion>();
+
+ // we only send back what we need
+ for (final Book b : bibles) {
+ final BibleVersion v = new BibleVersion();
+ v.setName(b.getName());
+ v.setInitials(b.getInitials());
+
+ final Language language = b.getLanguage();
+ if (language != null) {
+
+ v.setLanguage(language.getName());
+ }
+ v.setHasStrongs(b.hasFeature(FeatureType.STRONGS_NUMBERS));
+ versions.add(v);
+ }
+
+ // finally sort by initials
+ sort(versions, new Comparator<BibleVersion>() {
+ public int compare(final BibleVersion o1, final BibleVersion o2) {
+ return o1.getInitials().compareTo(o2.getInitials());
+ }
+ });
+
+ return versions;
+ }
+}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/XslHelper.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/XslHelper.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/XslHelper.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -4,9 +4,15 @@
import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.split;
+/**
+ * A helper class for use during XSL transformations
+ *
+ * @author Chris
+ *
+ */
public final class XslHelper {
- private static final int APPROXIMATE_ANCHOR_LENGTH = 56;
- private static final int APPROXIMATE_SPAN_LENGTH = 46;
+ private static final int APPROX_ANCHOR_LENGTH = 56;
+ private static final int APPROX_SPAN_LENGTH = 46;
private static final String START_ANCHOR = "<a href=\"";
private static final String START_FUNCTION_WRAPPER = "('";
private static final String END_FUNCTION_WRAPPER = "', this)";
@@ -26,7 +32,9 @@
* returns a "span" element for use in an HTML document
*
* @param strongsText the key straight from the OSIS text
+ * @param functionCall the javascript function that will be called upon click of the word
* @return a span containing all the strongs, seperated by spaces
+ *
*/
public static String getSpanFromAttributeName(final String strongsText, final String functionCall) {
final String[] strongs = split(strongsText, SEPARATORS);
@@ -35,7 +43,7 @@
}
// we transform each strong to something like: "<a href=\"%s\">%s</a>";
- final StringBuilder sb = new StringBuilder(APPROXIMATE_SPAN_LENGTH + strongs.length * APPROXIMATE_ANCHOR_LENGTH);
+ final StringBuilder sb = new StringBuilder(APPROX_SPAN_LENGTH + strongs.length * APPROX_ANCHOR_LENGTH);
String strongKey;
for (int ii = 0; ii < strongs.length; ii++) {
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/InterlinearProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/InterlinearProvider.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/InterlinearProvider.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,5 +1,12 @@
package com.tyndalehouse.step.core.xsl;
+/**
+ * An individual interlinear provider that cross-references text passed in using verse, strong, and morphology
+ * information
+ *
+ * @author Chris
+ *
+ */
public interface InterlinearProvider {
/**
* This is the more specific method
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/MultiInterlinearProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/MultiInterlinearProvider.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/MultiInterlinearProvider.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,5 +1,11 @@
package com.tyndalehouse.step.core.xsl;
+/**
+ * the Interface that a Mutli interlinear provider shall abide to
+ *
+ * @author Chris
+ *
+ */
public interface MultiInterlinearProvider {
/**
* This is the more specific method
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/XslConversionType.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/XslConversionType.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/XslConversionType.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -21,14 +21,25 @@
*/
private final String file;
+ /**
+ * giving a default XSL file to this Conversion type
+ */
private XslConversionType() {
this("default.xsl");
}
+ /**
+ * constructing a type associated with a specific file
+ *
+ * @param file the XSL transformation file
+ */
private XslConversionType(final String file) {
this.file = file;
}
+ /**
+ * @return the file associated with this type
+ */
public String getFile() {
return this.file;
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/DualKey.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/DualKey.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/DualKey.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -6,6 +6,8 @@
* A Strong Morph Map takes two keys, and gives one word back. The following DualKey relies on hashCode. The hash
* function relies on toString so T and S need to have fast toString().
*
+ * @param <T> the first part of the key
+ * @param <S> the second part of the key
* @author Chris
*
*/
@@ -13,6 +15,12 @@
private final T t;
private final S s;
+ /**
+ * creates a composite key
+ *
+ * @param t the first part of the key
+ * @param s the second part of the key
+ */
public DualKey(final T t, final S s) {
this.t = t;
this.s = s;
@@ -35,7 +43,7 @@
@Override
public int hashCode() {
// we need to return the same hashcode based on s and t
- return (this.t.toString().concat(this.s.toString())).hashCode();
+ return this.t.toString().concat(this.s.toString()).hashCode();
}
@Override
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImpl.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImpl.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -2,6 +2,8 @@
import static com.tyndalehouse.step.core.utils.StringConversionUtils.getAnyKey;
import static com.tyndalehouse.step.core.utils.StringConversionUtils.getStrongKey;
+import static java.lang.String.format;
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.commons.lang.StringUtils.split;
@@ -31,9 +33,9 @@
import com.tyndalehouse.step.core.xsl.InterlinearProvider;
/**
- * This object is not purposed to be used as a singleton. It builds up textual information on initialisation, and is
- * specific to requests. On initialisation, the OSIS XML is retrieved and iterated through to find all strong/morph
- * candidates
+ * This object is not purposed to be used as a singleton. It builds up textual information on initialisation,
+ * and is specific to requests. On initialisation, the OSIS XML is retrieved and iterated through to find all
+ * strong/morph candidates
*
* @author Chris
*
@@ -51,8 +53,8 @@
private final Map<DualKey<String, String>, List<String>> limitedAccuracy = new HashMap<DualKey<String, String>, List<String>>();
/**
- * finally, this is just a list of all the strongs and their mappings. Still would be fairly good as long as the
- * same word isn't used multiple times.
+ * finally, this is just a list of all the strongs and their mappings. Still would be fairly good as long
+ * as the same word isn't used multiple times.
*/
private final Map<String, String> worstAccuracy = new HashMap<String, String>();
@@ -69,6 +71,10 @@
}
final Book currentBook = Books.installed().getBook(version);
+ if (currentBook == null) {
+ throw new StepInternalException(format("Couldn't look up book: [%s]", version));
+ }
+
BookData bookData;
try {
@@ -88,12 +94,14 @@
// exposing package private constructor
}
+ @Override
public String getWord(final String verseNumber, final String strong, final String morph) {
// we use a linked hashset, because we want the behaviour of a set while we add to it,
// but at the end, we will want to return the elements in order
final Set<String> results = new LinkedHashSet<String>();
if (isBlank(strong)) {
// we might as well return, as we have no information to go on
+ return "";
}
// the keys passed in may have multiple references and morphologies, therefore, we need to lookup
@@ -106,7 +114,8 @@
boolean foundMatchForStrong = false;
final String strongKey = getAnyKey(s);
- // each could be using the morphs we have, so try them all - this gets skipped if we have no morphs
+ // each could be using the morphs we have, so try them all - this gets skipped if we have no
+ // morphs
for (final String m : morphs) {
// lookup (strong,morph) -> word first
final DualKey<String, String> key = new DualKey<String, String>(getStrongKey(strongKey), m);
@@ -162,7 +171,7 @@
final DualKey<String, String> key = new DualKey<String, String>(strong, verseNumber);
final List<String> list = this.limitedAccuracy.get(key);
- if (list != null && list.size() != 0) {
+ if (isNotEmpty(list)) {
return list.get(0);
}
}
@@ -256,14 +265,14 @@
/**
* Finally, we have some information to add to this provider. We try and add it in an efficient fashion.
*
- * So, how do we store this? The most meaningful piece of data is a STRONG number, since it identifies the word that
- * we want to retrieve. Without the strong number, we don't have any information at all. Therefore, the first level
- * of lookup should be by Strong number.
+ * So, how do we store this? The most meaningful piece of data is a STRONG number, since it identifies the
+ * word that we want to retrieve. Without the strong number, we don't have any information at all.
+ * Therefore, the first level of lookup should be by Strong number.
*
* Morphology-wise, each word might have a small number of options, so a linked list will do for this
*
- * One would think that strong -> morph -> word will be unique. In the case of having just strong, we should use
- * verse locality to maximise our chance of getting the right word (strong -> verse -> word)
+ * One would think that strong -> morph -> word will be unique. In the case of having just strong, we
+ * should use verse locality to maximise our chance of getting the right word (strong -> verse -> word)
*
* So in summary, we use: strong -> morph -> word strong -> verse -> list(word) (not unique)
*
@@ -272,7 +281,8 @@
* @param morph the morphology (identifies how the used is word in the sentence - i.e. grammar)
* @param word the word to be stored
*/
- void addTextualInfo(final String verseReference, final String strong, final String morph, final String word) {
+ void addTextualInfo(final String verseReference, final String strong, final String morph,
+ final String word) {
final String strongKey = getAnyKey(strong);
if (isNotBlank(strongKey) && isNotBlank(morph)) {
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/MultiInterlinearProviderImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/MultiInterlinearProviderImpl.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/MultiInterlinearProviderImpl.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -18,13 +18,14 @@
public class MultiInterlinearProviderImpl implements MultiInterlinearProvider {
/** we separate by commas and spaces */
private static final String VERSION_SEPARATOR = ", ";
- Map<String, InterlinearProvider> interlinearProviders = new HashMap<String, InterlinearProvider>();
+ private final Map<String, InterlinearProvider> interlinearProviders = new HashMap<String, InterlinearProvider>();
/**
* sets up the interlinear provider with the correct version and text scope.
*
- * @param version the version to use to set up the interlinear
- * @param textScope the text scope reference, defining the bounds of the lookup
+ * @param versions the versions to use to set up the interlinear
+ * @param textScope the reference, or passage range that should be considered when setting up the
+ * interlinear provider
*/
public MultiInterlinearProviderImpl(final String versions, final String textScope) {
// first check whether the values passed in are correct
@@ -40,7 +41,9 @@
}
}
- public String getWord(final String version, final String verseNumber, final String strong, final String morph) {
+ @Override
+ public String getWord(final String version, final String verseNumber, final String strong,
+ final String morph) {
return this.interlinearProviders.get(version).getWord(verseNumber, strong, morph);
}
}
Deleted: trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/service/impl/old_default.xsl
===================================================================
--- trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/service/impl/old_default.xsl 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/service/impl/old_default.xsl 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,1349 +0,0 @@
-<?xml version="1.0"?>
-<!--
- * Distribution License:
- * JSword is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License, version 2.1 as published by
- * the Free Software Foundation. This program is distributed in the hope
- * that it will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * The License is available on the internet at:
- * http://www.gnu.org/copyleft/lgpl.html
- * or by writing to:
- * Free Software Foundation, Inc.
- * 59 Temple Place - Suite 330
- * Boston, MA 02111-1307, USA
- *
- * Copyright: 2005
- * The copyright to this program is held by it's authors.
- *
- * ID: $Id: default.xsl 1943 2009-03-25 11:43:28Z dmsmith $
- -->
- <!--
- * Transforms OSIS to HTML for viewing within JSword browsers.
- * Note: There are custom protocols which the browser must handle.
- *
- * @see gnu.lgpl.License for license details.
- * The copyright to this program is held by it's authors.
- * @author Joe Walker [joe at eireneh dot com]
- * @author DM Smith [dmsmith555 at yahoo dot com]
- * @author Chris Burrell [chris at burrell dot me dot uk]
- -->
- <xsl:stylesheet
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- version="1.0"
- xmlns:jsword="http://xml.apache.org/xalan/java"
- extension-element-prefixes="jsword">
-
- <!-- Version 3.0 is necessary to get br to work correctly. -->
- <xsl:output method="html" version="3.0" omit-xml-declaration="yes" indent="no"/>
-
- <!-- Be very careful about introducing whitespace into the document.
- strip-space merely remove space between one tag and another tag.
- This may cause significant whitespace to be removed.
-
- It is easy to have apply-templates on a line to itself which if
- it encounters text before anything else will introduce whitespace.
- With the browser we are using, span will introduce whitespace
- but font does not. Therefore we use font as a span.
- -->
- <!-- gdef and hdef refer to hebrew and greek definitions keyed by strongs -->
- <!-- The absolute base for relative references. -->
- <xsl:param name="greek.def.protocol" select="'gdef:'"/>
- <xsl:param name="hebrew.def.protocol" select="'hdef:'"/>
- <xsl:param name="lex.def.protocol" select="'lex:'"/>
- <!-- currently these are not used, but they are for morphologic forms -->
- <xsl:param name="greek.morph.protocol" select="'gmorph:'"/>
- <xsl:param name="hebrew.morph.protocol" select="'hmorph:'"/>
-
- <!-- The absolute base for relative references. -->
- <xsl:param name="baseURL" select="''"/>
-
- <!-- Whether to show Strongs or not -->
- <xsl:param name="StrongsNumbers" select="'false'"/>
-
- <!-- Whether to show morphologic forms or not -->
- <xsl:param name="Morph" select="'false'"/>
-
- <!-- Whether to start each verse on an new line or not -->
- <xsl:param name="VLine" select="'false'"/>
-
- <!-- Whether to show non-canonical "headings" or not -->
- <xsl:param name="Headings" select="'false'"/>
-
- <!-- Whether to show notes or not -->
- <xsl:param name="Notes" select="'false'"/>
-
- <!-- Whether to have linking cross references or not -->
- <xsl:param name="XRef" select="'false'"/>
-
- <!-- Whether to output Verse numbers or not -->
- <xsl:param name="VNum" select="'false'"/>
-
- <!-- Whether to output Chapter and Verse numbers or not -->
- <xsl:param name="CVNum" select="'false'"/>
-
- <!-- Whether to output Book, Chapter and Verse numbers or not -->
- <xsl:param name="BCVNum" select="'false'"/>
-
- <!-- Whether to output superscript verse numbers or normal size ones -->
- <xsl:param name="TinyVNum" select="'false'"/>
-
- <!-- The order of display. Hebrew is rtl (right to left) -->
- <xsl:param name="direction" select="'ltr'"/>
-
- <!-- Create a global key factory from which OSIS ids will be generated -->
- <xsl:variable name="keyf" select="jsword:org.crosswire.jsword.passage.PassageKeyFactory.instance()"/>
- <!-- Create a global number shaper that can transform 0-9 into other number systems. -->
- <xsl:variable name="shaper" select="jsword:org.crosswire.common.icu.NumberShaper.new()"/>
-
- <!--=======================================================================-->
- <xsl:template match="/">
- <div>
- <!-- If there are notes, output a table with notes in the 2nd column. -->
- <!-- There is a rendering bug which prevents the notes from adhering to the right edge. -->
- <xsl:choose>
- <xsl:when test="$Notes = 'true' and //note[not(@type = 'x-strongsMarkup')]">
- <xsl:choose>
- <xsl:when test="$direction != 'rtl'">
- <table cols="2" cellpadding="5" cellspacing="5">
- <tr>
- <!-- The two rows are swapped until the bug is fixed. -->
- <td valign="top" class="notes">
- <p> </p>
- <xsl:apply-templates select="//verse" mode="print-notes"/>
- </td>
- <td valign="top" class="text">
- <xsl:apply-templates/>
- </td>
- </tr>
- </table>
- </xsl:when>
- <xsl:otherwise>
- <!-- reverse the table for Right to Left languages -->
- <table cols="2" cellpadding="5" cellspacing="5">
- <!-- In a right to left, the alignment should be reversed too -->
- <tr align="right">
- <td valign="top" class="notes">
- <p> </p>
- <xsl:apply-templates select="//note" mode="print-notes"/>
- </td>
- <td valign="top" class="text">
- <xsl:apply-templates/>
- </td>
- </tr>
- </table>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </div>
- </xsl:template>
-
- <!--=======================================================================-->
- <!--
- == A proper OSIS document has osis as its root.
- == We dig deeper for its content.
- -->
- <xsl:template match="osis">
- <xsl:apply-templates/>
- </xsl:template>
-
- <!--=======================================================================-->
- <!--
- == An OSIS document may contain more that one work.
- == Each work is held in an osisCorpus element.
- == If there is only one work, then this element will (should) be absent.
- == Process each document in turn.
- == It might be reasonable to dig into the header element of each work
- == and get its title.
- == Otherwise, we ignore the header and work elements and just process
- == the osisText elements.
- -->
- <xsl:template match="osisCorpus">
- <xsl:apply-templates select="osisText"/>
- </xsl:template>
-
- <!--=======================================================================-->
- <!--
- == Each work has an osisText element.
- == We ignore the header and work elements and process its div elements.
- == While divs can be milestoned, the osisText element requires container
- == divs.
- -->
- <xsl:template match="osisText">
- <xsl:apply-templates select="div"/>
- </xsl:template>
-
- <!-- Ignore headers and its elements -->
- <xsl:template match="header"/>
- <xsl:template match="revisionDesc"/>
- <xsl:template match="work"/>
- <!-- <xsl:template match="title"/> who's parent is work -->
- <xsl:template match="contributor"/>
- <xsl:template match="creator"/>
- <xsl:template match="subject"/>
- <!-- <xsl:template match="date"/> who's parent is work -->
- <xsl:template match="description"/>
- <xsl:template match="publisher"/>
- <xsl:template match="type"/>
- <xsl:template match="format"/>
- <xsl:template match="identifier"/>
- <xsl:template match="source"/>
- <xsl:template match="language"/>
- <xsl:template match="relation"/>
- <xsl:template match="coverage"/>
- <xsl:template match="rights"/>
- <xsl:template match="scope"/>
- <xsl:template match="workPrefix"/>
- <xsl:template match="castList"/>
- <xsl:template match="castGroup"/>
- <xsl:template match="castItem"/>
- <xsl:template match="actor"/>
- <xsl:template match="role"/>
- <xsl:template match="roleDesc"/>
- <xsl:template match="teiHeader"/>
- <xsl:template match="refSystem"/>
-
-
- <!-- Ignore titlePage -->
- <xsl:template match="titlePage"/>
-
- <!--=======================================================================-->
- <!--
- == Div provides the major containers for a work.
- == Divs are milestoneable.
- -->
- <xsl:template match="div[@type='x-center']">
- <div align="center">
- <xsl:apply-templates/>
- </div>
- </xsl:template>
-
- <xsl:template match="div">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="div" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!--=======================================================================-->
- <!-- Handle verses as containers and as a start verse. -->
- <xsl:template match="verse[not(@eID)]">
- <!-- output each preverse element in turn -->
- <xsl:for-each select=".//*[@subType = 'x-preverse' or @subtype = 'x-preverse']">
- <xsl:choose>
- <xsl:when test="local-name() = 'title'">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <h3 class="heading"><xsl:apply-templates /></h3>
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- <!-- Handle the KJV paragraph marker. -->
- <xsl:if test="milestone[@type = 'x-p']"><br/><br/></xsl:if>
- <!-- If the verse doesn't start on its own line and -->
- <!-- the verse is not the first verse of a set of siblings, -->
- <!-- output an extra space. -->
- <xsl:if test="$VLine = 'false' and preceding-sibling::*[local-name() = 'verse']">
- <xsl:text> </xsl:text>
- </xsl:if>
- <!-- Always output the verse -->
- <xsl:choose>
- <xsl:when test="$VLine = 'true'">
- <div class="l"><a name="{@osisID}"><xsl:call-template name="versenum"/></a><xsl:apply-templates/></div>
- </xsl:when>
- <xsl:otherwise>
- <span class="verse"><xsl:call-template name="versenum"/><xsl:apply-templates/></span>
- <!-- Follow the verse with an extra space -->
- <!-- when they don't start on lines to themselves -->
- <xsl:text> </xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="verse[not(@eID)]" mode="jesus">
- <!-- If the verse doesn't start on its own line and -->
- <!-- the verse is not the first verse of a set of siblings, -->
- <!-- output an extra space. -->
- <xsl:if test="$VLine = 'false' and preceding-sibling::*[local-name() = 'verse']">
- <xsl:text> </xsl:text>
- </xsl:if>
- <xsl:variable name="title" select=".//title"/>
- <xsl:if test="string-length($title) > 0">
- <h3 class="heading"><xsl:value-of select="$title"/></h3>
- </xsl:if>
- <!-- Handle the KJV paragraph marker. -->
- <xsl:if test="milestone[@type = 'x-p']"><br/><br/></xsl:if>
- <!-- Always output the verse -->
- <xsl:choose>
- <xsl:when test="$VLine = 'true'">
- <div class="l"><a name="{@osisID}"><xsl:call-template name="versenum"/></a><xsl:apply-templates mode="jesus"/></div>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="versenum"/><xsl:apply-templates mode="jesus"/>
- <!-- Follow the verse with an extra space -->
- <!-- when they don't start on lines to themselves -->
- <xsl:text> </xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="verse" mode="print-notes">
- <xsl:if test=".//note[not(@type) or not(@type = 'x-strongsMarkup')]">
- <xsl:variable name="passage" select="jsword:getValidKey($keyf, @osisID)"/>
- <a href="#{substring-before(concat(@osisID, ' '), ' ')}">
- <xsl:value-of select="jsword:getName($passage)"/>
- </a>
- <xsl:apply-templates select=".//note" mode="print-notes" />
- <div><xsl:text> </xsl:text></div>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="versenum">
- <!-- Are verse numbers wanted? -->
- <xsl:if test="$VNum = 'true'">
- <!-- An osisID can be a space separated list of them -->
- <xsl:variable name="firstOsisID" select="substring-before(concat(@osisID, ' '), ' ')"/>
- <xsl:variable name="book" select="substring-before($firstOsisID, '.')"/>
- <xsl:variable name="chapter" select="jsword:shape($shaper, substring-before(substring-after($firstOsisID, '.'), '.'))"/>
- <!-- If n is present use it for the number -->
- <xsl:variable name="verse">
- <xsl:choose>
- <xsl:when test="@n">
- <xsl:value-of select="jsword:shape($shaper, string(@n))"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="jsword:shape($shaper, substring-after(substring-after($firstOsisID, '.'), '.'))"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="versenum">
- <xsl:choose>
- <xsl:when test="$BCVNum = 'true'">
- <xsl:variable name="passage" select="jsword:getValidKey($keyf, @osisID)"/>
- <xsl:value-of select="jsword:getName($passage)"/>
- </xsl:when>
- <xsl:when test="$CVNum = 'true'">
- <xsl:value-of select="concat($chapter, ' : ', $verse)"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$verse"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <!--
- == Surround versenum with dup
- -->
- <xsl:choose>
- <xsl:when test="$TinyVNum = 'true' and $Notes = 'true'">
- <a name="{@osisID}"><span class="verseNumber"><xsl:value-of select="$versenum"/></span></a>
- </xsl:when>
- <xsl:when test="$TinyVNum = 'true' and $Notes = 'false'">
- <span class="verseNumber"><xsl:value-of select="$versenum"/></span>
- </xsl:when>
- <xsl:when test="$TinyVNum = 'false' and $Notes = 'true'">
- <a name="{@osisID}">(<xsl:value-of select="$versenum"/>)</a>
- <xsl:text> </xsl:text>
- </xsl:when>
- <xsl:otherwise>
- (<xsl:value-of select="$versenum"/>)
- <xsl:text> </xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- <xsl:if test="$VNum = 'false' and $Notes = 'true'">
- <a name="{@osisID}"></a>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="a">
- <a href="{@href}"><xsl:apply-templates/></a>
- </xsl:template>
-
- <xsl:template match="a" mode="jesus">
- <a href="{@href}"><xsl:apply-templates mode="jesus"/></a>
- </xsl:template>
-
- <!--=======================================================================-->
- <!-- When we encounter a note, we merely output a link to the note. -->
- <xsl:template match="note[@type = 'x-strongsMarkup']"/>
- <xsl:template match="note[@type = 'x-strongsMarkup']" mode="jesus"/>
- <xsl:template match="note[@type = 'x-strongsMarkup']" mode="print-notes"/>
-
- <xsl:template match="note">
- <xsl:if test="$Notes = 'true'">
- <!-- If there is a following sibling that is a note, emit a separator -->
- <xsl:variable name="siblings" select="../child::node()"/>
- <xsl:variable name="next-position" select="position() + 1"/>
- <xsl:choose>
- <xsl:when test="name($siblings[$next-position]) = 'note'">
- <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a>, </sup>
- </xsl:when>
- <xsl:otherwise>
- <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a></sup>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="note" mode="jesus">
- <xsl:if test="$Notes = 'true'">
- <!-- If there is a following sibling that is a note, emit a separator -->
- <xsl:variable name="siblings" select="../child::node()"/>
- <xsl:variable name="next-position" select="position() + 1"/>
- <xsl:choose>
- <xsl:when test="$siblings[$next-position] and name($siblings[$next-position]) = 'note'">
- <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a>, </sup>
- </xsl:when>
- <xsl:otherwise>
- <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a></sup>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="note" mode="print-notes">
- <div class="margin">
- <strong><xsl:call-template name="generateNoteXref"/></strong>
- <a name="note-{generate-id(.)}">
- <xsl:text> </xsl:text>
- </a>
- <xsl:apply-templates/>
- </div>
- </xsl:template>
-
- <!--
- == If the n attribute is present then use that for the cross ref otherwise create a letter.
- == Note: numbering restarts with each verse.
- -->
- <xsl:template name="generateNoteXref">
- <xsl:choose>
- <xsl:when test="@n">
- <xsl:value-of select="@n"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:number level="any" from="/osis//verse" format="a"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="p">
- <p><xsl:apply-templates/></p>
- </xsl:template>
-
- <xsl:template match="p" mode="jesus">
- <p><xsl:apply-templates mode="jesus"/></p>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="p" mode="print-notes">
- <!-- FIXME: This ignores text in the note. -->
- <!-- don't put para's in notes -->
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="w">
- <!-- Output the content followed by all the lemmas and then all the morphs. -->
- <xsl:apply-templates/>
-
- <!--
- except when followed by a text node or non-printing node.
- This is true whether the href is output or not.
- -->
- <xsl:variable name="siblings" select="../child::node()"/>
- <xsl:variable name="next-position" select="position() + 1"/>
- <xsl:if test="$siblings[$next-position] and name($siblings[$next-position]) != ''">
- <xsl:text> </xsl:text>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="w" mode="jesus">
- <!-- Output the content followed by all the lemmas and then all the morphs. -->
- <xsl:apply-templates mode="jesus"/>
- <!--
- except when followed by a text node or non-printing node.
- This is true whether the href is output or not.
- -->
- <xsl:variable name="siblings" select="../child::node()"/>
- <xsl:variable name="next-position" select="position() + 1"/>
- <xsl:if test="$siblings[$next-position] and name($siblings[$next-position]) != ''">
- <xsl:text> </xsl:text>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="seg">
- <xsl:choose>
- <xsl:when test="starts-with(@type, 'color:')">
- <font color="{substring-before(substring-after(@type, 'color: '), ';')}"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="starts-with(@type, 'font-size:')">
- <font size="{substring-before(substring-after(@type, 'font-size: '), ';')}"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="@type = 'x-variant'">
- <xsl:if test="@subType = 'x-class-1'">
- <xsl:apply-templates/>
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="seg" mode="jesus">
- <xsl:choose>
- <xsl:when test="starts-with(@type, 'color:')">
- <font color="{substring-before(substring-after(@type, 'color: '), ';')}"><xsl:apply-templates mode="jesus"/></font>
- </xsl:when>
- <xsl:when test="starts-with(@type, 'font-size:')">
- <font size="{substring-before(substring-after(@type, 'font-size: '), ';')}"><xsl:apply-templates mode="jesus"/></font>
- </xsl:when>
- <xsl:when test="@type = 'x-variant'">
- <xsl:if test="@subType = 'x-class:1'">
- <xsl:apply-templates mode="jesus"/>
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates mode="jesus"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!--=======================================================================-->
- <!-- expansion is OSIS, expan is TEI -->
- <xsl:template match="abbr">
- <font class="abbr">
- <xsl:if test="@expansion">
- <xsl:attribute name="title">
- <xsl:value-of select="@expansion"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="@expan">
- <xsl:attribute name="title">
- <xsl:value-of select="@expan"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:apply-templates/>
- </font>
- </xsl:template>
-
- <xsl:template match="abbr" mode="jesus">
- <font class="abbr">
- <xsl:if test="@expansion">
- <xsl:attribute name="title">
- <xsl:value-of select="@expansion"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="@expan">
- <xsl:attribute name="title">
- <xsl:value-of select="@expan"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:apply-templates mode="jesus"/>
- </font>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="speaker[@who = 'Jesus']">
- <span class="jesus"><xsl:apply-templates mode="jesus"/></span>
- </xsl:template>
-
- <xsl:template match="speaker">
- <span class="speech"><xsl:apply-templates/></span>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="title[@subType ='x-preverse' or @subtype = 'x-preverse']">
- <!-- Done by a line in [verse]
- <h3 class="heading">
- <xsl:apply-templates/>
- </h3>
- -->
- </xsl:template>
-
- <xsl:template match="title[@subType ='x-preverse' or @subtype = 'x-preverse']" mode="jesus">
- <!-- Done by a line in [verse]
- <h3 class="heading">
- <xsl:apply-templates/>
- </h3>
- -->
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="title[@level]">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <xsl:choose>
- <xsl:when test="@level = '1'">
- <h1 class="level"><xsl:apply-templates/></h1>
- </xsl:when>
- <xsl:when test="@level = '2'">
- <h2 class="level"><xsl:apply-templates/></h2>
- </xsl:when>
- <xsl:when test="@level = '3'">
- <h3 class="level"><xsl:apply-templates/></h3>
- </xsl:when>
- <xsl:when test="@level = '4'">
- <h4 class="level"><xsl:apply-templates/></h4>
- </xsl:when>
- <xsl:when test="@level = '5'">
- <h5 class="level"><xsl:apply-templates/></h5>
- </xsl:when>
- <xsl:otherwise>
- <h6 class="level"><xsl:apply-templates/></h6>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="title[@level]" mode="jesus">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <xsl:choose>
- <xsl:when test="@level = '1'">
- <h1 class="level"><xsl:apply-templates/></h1>
- </xsl:when>
- <xsl:when test="@level = '2'">
- <h2 class="level"><xsl:apply-templates/></h2>
- </xsl:when>
- <xsl:when test="@level = '3'">
- <h3 class="level"><xsl:apply-templates/></h3>
- </xsl:when>
- <xsl:when test="@level = '4'">
- <h4 class="level"><xsl:apply-templates/></h4>
- </xsl:when>
- <xsl:when test="@level = '5'">
- <h5 class="level"><xsl:apply-templates/></h5>
- </xsl:when>
- <xsl:otherwise>
- <h6 class="level"><xsl:apply-templates/></h6>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="title">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <h2 class="heading"><xsl:apply-templates/></h2>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="title" mode="jesus">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <h2 class="heading"><xsl:apply-templates/></h2>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="reference">
- <xsl:choose>
- <xsl:when test="$XRef = 'true'">
- <a href="bible://{@osisRef}"><xsl:apply-templates/></a>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="reference" mode="jesus">
- <xsl:choose>
- <xsl:when test="$XRef = 'true'">
- <a href="bible://{@osisRef}"><xsl:apply-templates mode="jesus"/></a>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates mode="jesus"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="caption">
- <div class="caption"><xsl:apply-templates/></div>
- </xsl:template>
-
- <xsl:template match="caption" mode="jesus">
- <div class="caption"><xsl:apply-templates/></div>
- </xsl:template>
-
- <xsl:template match="catchWord">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="catchWord" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!--
- <cell> is handled shortly after <table> below and thus does not appear
- here.
- -->
-
- <xsl:template match="closer">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="closer" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <xsl:template match="date">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="date" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <xsl:template match="divineName">
- <xsl:apply-templates mode="small-caps"/>
- </xsl:template>
-
- <xsl:template match="divineName" mode="jesus">
- <xsl:apply-templates mode="small-caps"/>
- </xsl:template>
-
- <xsl:template match="figure">
- <div class="figure">
- <xsl:choose>
- <xsl:when test="starts-with(@src, '/')">
- <img src="{concat($baseURL, @src)}"/> <!-- FIXME: Not necessarily an image... -->
- </xsl:when>
- <xsl:otherwise>
- <img src="{concat($baseURL, '/', @src)}"/> <!-- FIXME: Not necessarily an image... -->
- </xsl:otherwise>
- </xsl:choose>
- <xsl:apply-templates/>
- </div>
- </xsl:template>
-
- <xsl:template match="figure" mode="jesus">
- <div class="figure">
- <xsl:choose>
- <xsl:when test="starts-with(@src, '/')">
- <img src="{concat($baseURL, @src)}"/> <!-- FIXME: Not necessarily an image... -->
- </xsl:when>
- <xsl:otherwise>
- <img src="{concat($baseURL, '/', @src)}"/> <!-- FIXME: Not necessarily an image... -->
- </xsl:otherwise>
- </xsl:choose>
- <xsl:apply-templates mode="jesus"/>
- </div>
- </xsl:template>
-
- <xsl:template match="foreign">
- <em class="foreign"><xsl:apply-templates/></em>
- </xsl:template>
-
- <xsl:template match="foreign" mode="jesus">
- <em class="foreign"><xsl:apply-templates mode="jesus"/></em>
- </xsl:template>
-
- <!-- This is a subheading. -->
- <xsl:template match="head//head">
- <h5 class="head"><xsl:apply-templates/></h5>
- </xsl:template>
-
- <!-- This is a top-level heading. -->
- <xsl:template match="head">
- <h4 class="head"><xsl:apply-templates/></h4>
- </xsl:template>
-
- <xsl:template match="index">
- <a name="index{@id}" class="index"/>
- </xsl:template>
-
- <xsl:template match="inscription">
- <xsl:apply-templates mode="small-caps"/>
- </xsl:template>
-
- <xsl:template match="inscription" mode="jesus">
- <xsl:apply-templates mode="small-caps"/>
- </xsl:template>
-
- <xsl:template match="item">
- <li class="item"><xsl:apply-templates/></li>
- </xsl:template>
-
- <xsl:template match="item" mode="jesus">
- <li class="item"><xsl:apply-templates mode="jesus"/></li>
- </xsl:template>
-
- <!--
- <item> and <label> are covered by <list> below and so do not appear here.
- -->
-
- <xsl:template match="lg">
- <div class="lg"><xsl:apply-templates/></div>
- </xsl:template>
-
- <xsl:template match="lg" mode="jesus">
- <div class="lg"><xsl:apply-templates mode="jesus"/></div>
- </xsl:template>
-
- <xsl:template match="lg[@sID or @eID]"/>
- <xsl:template match="lg[@sID or @eID]" mode="jesus"/>
-
- <xsl:template match="l[@sID]"/>
- <xsl:template match="l[@sID]" mode="jesus"/>
-
- <xsl:template match="l[@eID]"><br/></xsl:template>
- <xsl:template match="l[@eID]" mode="jesus"><br/></xsl:template>
-
- <xsl:template match="l">
- <xsl:apply-templates/><br/>
- </xsl:template>
-
- <xsl:template match="l" mode="jesus">
- <xsl:apply-templates mode="jesus"/><br/>
- </xsl:template>
-
- <!-- While a BR is a break, if it is immediately followed by punctuation,
- indenting this rule can introduce whitespace.
- -->
- <xsl:template match="lb"><br /></xsl:template>
- <xsl:template match="lb" mode="jesus"><br/></xsl:template>
-
- <xsl:template match="list">
- <xsl:choose>
- <xsl:when test="label">
- <!-- If there are <label>s in the list, it's a <dl>. -->
- <dl class="list">
- <xsl:for-each select="node()">
- <xsl:choose>
- <xsl:when test="self::label">
- <dt class="label"><xsl:apply-templates/></dt>
- </xsl:when>
- <xsl:when test="self::item">
- <dd class="item"><xsl:apply-templates/></dd>
- </xsl:when>
- <xsl:when test="self::list">
- <dd class="list-wrapper"><xsl:apply-templates select="."/></dd>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </dl>
- </xsl:when>
-
- <xsl:otherwise>
- <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
- <ul class="list">
- <xsl:for-each select="node()">
- <xsl:choose>
- <xsl:when test="self::item">
- <li class="item"><xsl:apply-templates/></li>
- </xsl:when>
- <xsl:when test="self::list">
- <li class="list-wrapper"><xsl:apply-templates select="."/></li>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </ul>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
-
- <xsl:template match="list" mode="jesus">
- <xsl:choose>
- <xsl:when test="label">
- <!-- If there are <label>s in the list, it's a <dl>. -->
- <dl class="list">
- <xsl:for-each select="node()">
- <xsl:choose>
- <xsl:when test="self::label">
- <dt class="label"><xsl:apply-templates mode="jesus"/></dt>
- </xsl:when>
- <xsl:when test="self::item">
- <dd class="item"><xsl:apply-templates mode="jesus"/></dd>
- </xsl:when>
- <xsl:when test="self::list">
- <dd class="list-wrapper"><xsl:apply-templates select="." mode="jesus"/></dd>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates mode="jesus"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </dl>
- </xsl:when>
-
- <xsl:otherwise>
- <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
- <ul class="list">
- <xsl:for-each select="node()">
- <xsl:choose>
- <xsl:when test="self::item">
- <li class="item"><xsl:apply-templates mode="jesus"/></li>
- </xsl:when>
- <xsl:when test="self::list">
- <li class="list-wrapper"><xsl:apply-templates select="." mode="jesus"/></li>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates mode="jesus"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </ul>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="mentioned">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="mentioned" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!-- Milestones represent characteristics of the original manuscript.
- == that are being preserved. For this reason, most are ignored.
- ==
- == The defined types are:
- == column Marks the end of a column where there is a multi-column display.
- == footer Marks the footer region of a page.
- == halfLine Used to mark half-line units if not otherwise encoded.
- == header Marks the header region of a page.
- == line Marks line breaks, particularly important in recording appearance of an original text, such as a manuscript.
- == pb Marks a page break in a text.
- == screen Marks a preferred place for breaks in an on-screen rendering of the text.
- == cQuote Marks the location of a continuation quote mark, with marker containing the publishers mark.
- -->
- <!-- This is used by the KJV for paragraph markers. -->
- <xsl:template match="milestone[@type = 'x-p']"><xsl:text> </xsl:text><xsl:value-of select="@marker"/><xsl:text> </xsl:text></xsl:template>
- <xsl:template match="milestone[@type = 'x-p']" mode="jesus"><xsl:text> </xsl:text><xsl:value-of select="@marker"/><xsl:text> </xsl:text></xsl:template>
-
- <xsl:template match="milestone[@type = 'cQuote']">
- <xsl:value-of select="@marker"/>
- </xsl:template>
-
- <xsl:template match="milestone[@type = 'cQuote']" mode="jesus">
- <xsl:value-of select="@marker"/>
- </xsl:template>
-
- <xsl:template match="milestone[@type = 'line']"><br/></xsl:template>
-
- <xsl:template match="milestone[@type = 'line']" mode="jesus"><br/></xsl:template>
-
- <!--
- == Milestone start and end are deprecated.
- == At this point we expect them to not be in the document.
- == These have been replace with milestoneable elements.
- -->
- <xsl:template match="milestoneStart"/>
- <xsl:template match="milestoneEnd"/>
-
- <xsl:template match="name">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="name" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!-- If there is a milestoned q then just output a quotation mark -->
- <xsl:template match="q[@sID or @eID]">
- <xsl:choose>
- <xsl:when test="@marker"><xsl:value-of select="@marker"/></xsl:when>
- <!-- The chosen mark should be based on the work's author's locale. -->
- <xsl:otherwise>"</xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="q[@sID or @eID]" mode="jesus">
- <xsl:choose>
- <xsl:when test="@marker"><xsl:value-of select="@marker"/></xsl:when>
- <!-- The chosen mark should be based on the work's author's locale. -->
- <xsl:otherwise>"</xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="q[@who = 'Jesus']">
- <span class="jesus"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></span>
- </xsl:template>
-
- <xsl:template match="q[@type = 'blockquote']">
- <span class="q"><xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/></span>
- </xsl:template>
-
- <xsl:template match="q[@type = 'blockquote']" mode="jesus">
- <span class="q"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></span>
- </xsl:template>
-
- <xsl:template match="q[@type = 'citation']">
- <span class="q"><xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/></span>
- </xsl:template>
-
- <xsl:template match="q[@type = 'citation']" mode="jesus">
- <span class="q"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></span>
- </xsl:template>
-
- <xsl:template match="q[@type = 'embedded']">
- <xsl:choose>
- <xsl:when test="@marker">
- <xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/>
- </xsl:when>
- <xsl:otherwise>
- <quote class="q"><xsl:apply-templates/></quote>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="q[@type = 'embedded']" mode="jesus">
- <xsl:choose>
- <xsl:when test="@marker">
- <xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/>
- </xsl:when>
- <xsl:otherwise>
- <quote class="q"><xsl:apply-templates/></quote>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- An alternate reading. -->
- <xsl:template match="rdg">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="rdg" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!--
- <row> is handled near <table> below and so does not appear here.
- -->
-
- <xsl:template match="salute">
- <xsl:apply-templates/>
- </xsl:template>
-
- <!-- Avoid adding whitespace -->
- <xsl:template match="salute" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <xsl:template match="signed">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="signed" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <xsl:template match="speech">
- <div class="speech"><xsl:apply-templates/></div>
- </xsl:template>
-
- <xsl:template match="speech" mode="jesus">
- <div class="speech"><xsl:apply-templates mode="jesus"/></div>
- </xsl:template>
-
- <xsl:template match="table">
- <table class="table">
- <xsl:copy-of select="@rows|@cols"/>
- <xsl:if test="head">
- <thead class="head"><xsl:apply-templates select="head"/></thead>
- </xsl:if>
- <tbody><xsl:apply-templates select="row"/></tbody>
- </table>
- </xsl:template>
-
- <xsl:template match="row">
- <tr class="row"><xsl:apply-templates/></tr>
- </xsl:template>
-
- <xsl:template match="cell">
- <xsl:variable name="element-name">
- <xsl:choose>
- <xsl:when test="@role = 'label'">
- <xsl:text>th</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>td</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="cell-direction">
- <xsl:if test="@xml:lang">
- <xsl:call-template name="getDirection">
- <xsl:with-param name="lang"><xsl:value-of select="@xml:lang"/></xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:variable>
- <xsl:element name="{$element-name}">
- <xsl:attribute name="class">cell</xsl:attribute>
- <xsl:attribute name="valign">top</xsl:attribute>
- <xsl:if test="@xml:lang">
- <xsl:attribute name="dir">
- <xsl:value-of select="$cell-direction"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="$cell-direction = 'rtl'">
- <xsl:attribute name="align">
- <xsl:value-of select="'right'"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="@rows">
- <xsl:attribute name="rowspan">
- <xsl:value-of select="@rows"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="@cols">
- <xsl:attribute name="colspan">
- <xsl:value-of select="@cols"/>
- </xsl:attribute>
- </xsl:if>
- <!-- hack alert -->
- <xsl:choose>
- <xsl:when test="$cell-direction = 'rtl'">
- <xsl:text>‫</xsl:text><xsl:apply-templates/><xsl:text>‬</xsl:text>
- </xsl:when>
- <xsl:when test="$cell-direction = 'ltr'">
- <xsl:text>‪</xsl:text><xsl:apply-templates/><xsl:text>‬</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:element>
- </xsl:template>
-
- <xsl:template match="transChange">
- <span><em><xsl:apply-templates/></em></span>
- </xsl:template>
- <xsl:template match="transChange" mode="jesus">
- <span class="w"><em><xsl:apply-templates/></em></span>
- </xsl:template>
-
- <!-- @type is OSIS, @rend is TEI -->
- <xsl:template match="hi">
- <xsl:variable name="style">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@rend"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$style = 'acrostic'">
- <xsl:apply-templates/>
- </xsl:when>
- <xsl:when test="$style = 'bold'">
- <strong><xsl:apply-templates/></strong>
- </xsl:when>
- <xsl:when test="$style = 'emphasis'">
- <em><xsl:apply-templates/></em>
- </xsl:when>
- <xsl:when test="$style = 'illuminated'">
- <strong><em><xsl:apply-templates/></em></strong>
- </xsl:when>
- <xsl:when test="$style = 'italic'">
- <em><xsl:apply-templates/></em>
- </xsl:when>
- <xsl:when test="$style = 'line-through'">
- <span class="strike"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:when test="$style = 'normal'">
- <span class="normal"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:when test="$style = 'small-caps'">
- <span class="small-caps"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:when test="$style = 'sub'">
- <sub><xsl:apply-templates/></sub>
- </xsl:when>
- <xsl:when test="$style = 'super'">
- <sup><xsl:apply-templates/></sup>
- </xsl:when>
- <xsl:when test="$style = 'underline'">
- <span class="underline"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:when test="$style = 'x-caps'">
- <span class="caps"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="hi" mode="jesus">
- <xsl:variable name="style">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@rend"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$style = 'acrostic'">
- <xsl:apply-templates/>
- </xsl:when>
- <xsl:when test="$style = 'bold'">
- <strong><xsl:apply-templates/></strong>
- </xsl:when>
- <xsl:when test="$style = 'emphasis'">
- <em><xsl:apply-templates/></em>
- </xsl:when>
- <xsl:when test="$style = 'illuminated'">
- <strong><em><xsl:apply-templates/></em></strong>
- </xsl:when>
- <xsl:when test="$style = 'italic'">
- <em><xsl:apply-templates/></em>
- </xsl:when>
- <xsl:when test="$style = 'line-through'">
- <span class="strike"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:when test="$style = 'normal'">
- <span class="normal"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:when test="$style = 'small-caps'">
- <span class="small-caps"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:when test="$style = 'sub'">
- <sub><xsl:apply-templates/></sub>
- </xsl:when>
- <xsl:when test="$style = 'super'">
- <sup><xsl:apply-templates/></sup>
- </xsl:when>
- <xsl:when test="$style = 'underline'">
- <span class="underline"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:when test="$style = 'x-caps'">
- <span class="caps"><xsl:apply-templates/></span>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!--
- The following elements are actually TEI and there is some expectation
- that these will make it into OSIS.
- -->
- <xsl:template match="superentry">
- <!-- output each preverse element in turn -->
- <xsl:for-each select="entry|entryFree">
- <xsl:apply-templates/><br/><br/>
- </xsl:for-each>
- </xsl:template>
-
- <xsl:template match="entry">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="entryFree">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="form">
- <xsl:apply-templates/><br/>
- </xsl:template>
-
- <xsl:template match="orth">
- <font class="orth"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="pron">
- <font class="pron"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="etym">
- <font class="etym"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="def">
- <font class="def"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="usg">
- <font class="usg"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="@xml:lang">
- <xsl:variable name="dir">
- <xsl:if test="@xml:lang">
- <xsl:call-template name="getDirection">
- <xsl:with-param name="lang"><xsl:value-of select="@xml:lang"/></xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:variable>
- <xsl:if test="$dir">
- <xsl:attribute name="dir">
- <xsl:value-of select="$dir"/>
- </xsl:attribute>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="text()" mode="small-caps">
- <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
- </xsl:template>
-
- <!--
- The direction is deduced from the xml:lang attribute and is assumed to be meaningful for those elements.
- Note: there is a bug that prevents dir=rtl from working.
- see: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4296022 and 4866977
- -->
- <xsl:template name="getDirection">
- <xsl:param name="lang"/>
- <xsl:choose>
- <xsl:when test="$lang = 'he' or $lang = 'ar' or $lang = 'fa' or $lang = 'ur' or $lang = 'syr'">
- <xsl:value-of select="'rtl'"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="'ltr'"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="string-replace-all">
- <xsl:param name="text" />
- <xsl:param name="replace" />
- <xsl:param name="by" />
- <xsl:choose>
- <xsl:when test="contains($text, $replace)">
- <xsl:value-of select="substring-before($text,$replace)" />
- <xsl:value-of select="$by" />
- <xsl:call-template name="string-replace-all">
- <xsl:with-param name="text" select="substring-after($text,$replace)" />
- <xsl:with-param name="replace" select="$replace" />
- <xsl:with-param name="by" select="$by" />
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$text" />
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-</xsl:stylesheet>
Deleted: trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/service/impl/old_interlinear.xsl
===================================================================
--- trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/service/impl/old_interlinear.xsl 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/main/resources/com/tyndalehouse/step/core/service/impl/old_interlinear.xsl 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,1555 +0,0 @@
-<?xml version="1.0"?>
-<!--
- * Distribution License:
- * JSword is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License, version 2.1 as published by
- * the Free Software Foundation. This program is distributed in the hope
- * that it will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * The License is available on the internet at:
- * http://www.gnu.org/copyleft/lgpl.html
- * or by writing to:
- * Free Software Foundation, Inc.
- * 59 Temple Place - Suite 330
- * Boston, MA 02111-1307, USA
- *
- * Copyright: 2005
- * The copyright to this program is held by it's authors.
- *
- * ID: $Id: default.xsl 1943 2009-03-25 11:43:28Z dmsmith $
- -->
- <!--
- * Transforms OSIS to HTML for viewing within JSword browsers.
- * Note: There are custom protocols which the browser must handle.
- *
- * @see gnu.lgpl.License for license details.
- * The copyright to this program is held by it's authors.
- * @author Joe Walker [joe at eireneh dot com]
- * @author DM Smith [dmsmith555 at yahoo dot com]
- * @author Chris Burrell [chris at burrell dot me dot uk]
- -->
- <xsl:stylesheet
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- version="1.0"
- xmlns:jsword="http://xml.apache.org/xalan/java"
- extension-element-prefixes="jsword">
-
- <!-- Version 3.0 is necessary to get br to work correctly. -->
- <xsl:output method="html" version="3.0" omit-xml-declaration="yes" indent="no"/>
-
- <!-- Be very careful about introducing whitespace into the document.
- strip-space merely remove space between one tag and another tag.
- This may cause significant whitespace to be removed.
-
- It is easy to have apply-templates on a line to itself which if
- it encounters text before anything else will introduce whitespace.
- With the browser we are using, span will introduce whitespace
- but font does not. Therefore we use font as a span.
- -->
- <!-- gdef and hdef refer to hebrew and greek definitions keyed by strongs -->
- <xsl:param name="greek.def.protocol" select="'gdef:'"/>
- <xsl:param name="hebrew.def.protocol" select="'hdef:'"/>
- <xsl:param name="lex.def.protocol" select="'lex:'"/>
- <!-- currently these are not used, but they are for morphologic forms -->
- <xsl:param name="greek.morph.protocol" select="'gmorph:'"/>
- <xsl:param name="hebrew.morph.protocol" select="'hmorph:'"/>
-
- <!-- The absolute base for relative references. -->
- <xsl:param name="baseURL" select="''"/>
-
- <!-- Whether to show Strongs or not -->
- <xsl:param name="StrongsNumbers" select="'false'"/>
-
- <!-- Whether to show morphologic forms or not -->
- <xsl:param name="Morph" select="'false'"/>
-
- <!-- Whether to start each verse on an new line or not -->
- <xsl:param name="VLine" select="'false'"/>
-
- <!-- Whether to show non-canonical "headings" or not -->
- <xsl:param name="Headings" select="'true'"/>
-
- <!-- Whether to show notes or not -->
- <xsl:param name="Notes" select="'false'"/>
-
- <!-- Whether to have linking cross references or not -->
- <xsl:param name="XRef" select="'false'"/>
-
- <!-- Whether to output no Verse numbers -->
- <xsl:param name="NoVNum" select="'false'"/>
-
- <!-- Whether to output Verse numbers or not -->
- <xsl:param name="VNum" select="'true'"/>
-
- <!-- Whether to output Chapter and Verse numbers or not -->
- <xsl:param name="CVNum" select="'false'"/>
-
- <!-- Whether to output Book, Chapter and Verse numbers or not -->
- <xsl:param name="BCVNum" select="'false'"/>
-
- <!-- Whether to output superscript verse numbers or normal size ones -->
- <xsl:param name="TinyVNum" select="'true'"/>
-
- <!-- The order of display. Hebrew is rtl (right to left) -->
- <xsl:param name="direction" select="'ltr'"/>
-
- <!-- Whether to show an interlinear and the provider helping with the lookup -->
- <xsl:param name="Interlinear" select="'false'" />
- <xsl:param name="interlinearVersion" select="''" />
- <xsl:param name="interlinearReference" select="''" />
-
- <!-- Create a global key factory from which OSIS ids will be generated -->
- <xsl:variable name="keyf" select="jsword:org.crosswire.jsword.passage.PassageKeyFactory.instance()"/>
- <!-- Create a global number shaper that can transform 0-9 into other number systems. -->
- <xsl:variable name="shaper" select="jsword:org.crosswire.common.icu.NumberShaper.new()"/>
-
- <!-- set up interlinear provider, if we have requested it -->
- <xsl:variable name="interlinearProvider" select="jsword:com.tyndalehouse.step.core.xsl.impl.InterlinearProviderImpl.new(string($interlinearVersion), string($interlinearReference))" />
-
- <!--=======================================================================-->
- <xsl:template match="/">
- <div>
- <!-- If there are notes, output a table with notes in the 2nd column. -->
- <!-- There is a rendering bug which prevents the notes from adhering to the right edge. -->
- <xsl:choose>
- <xsl:when test="$Notes = 'true' and //note[not(@type = 'x-strongsMarkup')]">
- <xsl:choose>
- <xsl:when test="$direction != 'rtl'">
- <table cols="2" cellpadding="5" cellspacing="5">
- <tr>
- <!-- The two rows are swapped until the bug is fixed. -->
- <td valign="top" class="notes">
- <p> </p>
- <xsl:apply-templates select="//verse" mode="print-notes"/>
- </td>
- <td valign="top" class="text">
- <xsl:apply-templates/>
- </td>
- </tr>
- </table>
- </xsl:when>
- <xsl:otherwise>
- <!-- reverse the table for Right to Left languages -->
- <table cols="2" cellpadding="5" cellspacing="5">
- <!-- In a right to left, the alignment should be reversed too -->
- <tr align="right">
- <td valign="top" class="notes">
- <p> </p>
- <xsl:apply-templates select="//note" mode="print-notes"/>
- </td>
- <td valign="top" class="text">
- <xsl:apply-templates/>
- </td>
- </tr>
- </table>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </div>
- </xsl:template>
-
- <!--=======================================================================-->
- <!--
- == A proper OSIS document has osis as its root.
- == We dig deeper for its content.
- -->
- <xsl:template match="osis">
- <xsl:apply-templates/>
- </xsl:template>
-
- <!--=======================================================================-->
- <!--
- == An OSIS document may contain more that one work.
- == Each work is held in an osisCorpus element.
- == If there is only one work, then this element will (should) be absent.
- == Process each document in turn.
- == It might be reasonable to dig into the header element of each work
- == and get its title.
- == Otherwise, we ignore the header and work elements and just process
- == the osisText elements.
- -->
- <xsl:template match="osisCorpus">
- <xsl:apply-templates select="osisText"/>
- </xsl:template>
-
- <!--=======================================================================-->
- <!--
- == Each work has an osisText element.
- == We ignore the header and work elements and process its div elements.
- == While divs can be milestoned, the osisText element requires container
- == divs.
- -->
- <xsl:template match="osisText">
- <xsl:apply-templates select="div"/>
- </xsl:template>
-
- <!-- Ignore headers and its elements -->
- <xsl:template match="header"/>
- <xsl:template match="revisionDesc"/>
- <xsl:template match="work"/>
- <!-- <xsl:template match="title"/> who's parent is work -->
- <xsl:template match="contributor"/>
- <xsl:template match="creator"/>
- <xsl:template match="subject"/>
- <!-- <xsl:template match="date"/> who's parent is work -->
- <xsl:template match="description"/>
- <xsl:template match="publisher"/>
- <xsl:template match="type"/>
- <xsl:template match="format"/>
- <xsl:template match="identifier"/>
- <xsl:template match="source"/>
- <xsl:template match="language"/>
- <xsl:template match="relation"/>
- <xsl:template match="coverage"/>
- <xsl:template match="rights"/>
- <xsl:template match="scope"/>
- <xsl:template match="workPrefix"/>
- <xsl:template match="castList"/>
- <xsl:template match="castGroup"/>
- <xsl:template match="castItem"/>
- <xsl:template match="actor"/>
- <xsl:template match="role"/>
- <xsl:template match="roleDesc"/>
- <xsl:template match="teiHeader"/>
- <xsl:template match="refSystem"/>
-
-
- <!-- Ignore titlePage -->
- <xsl:template match="titlePage"/>
-
- <!--=======================================================================-->
- <!--
- == Div provides the major containers for a work.
- == Divs are milestoneable.
- -->
- <xsl:template match="div[@type='x-center']">
- <div align="center">
- <xsl:apply-templates/>
- </div>
- </xsl:template>
-
- <xsl:template match="div">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="div" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!--=======================================================================-->
- <!-- Handle verses as containers and as a start verse. -->
- <xsl:template match="verse[not(@eID)]">
- <!-- output each preverse element in turn -->
- <xsl:for-each select=".//*[@subType = 'x-preverse' or @subtype = 'x-preverse']">
- <xsl:choose>
- <xsl:when test="local-name() = 'title'">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <h3 class="heading"><xsl:apply-templates /></h3>
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- <!-- Handle the KJV paragraph marker. -->
- <xsl:if test="milestone[@type = 'x-p']"><br/><br/></xsl:if>
- <!-- If the verse doesn't start on its own line and -->
- <!-- the verse is not the first verse of a set of siblings, -->
- <!-- output an extra space. -->
- <xsl:if test="$VLine = 'false' and preceding-sibling::*[local-name() = 'verse']">
- <xsl:text> </xsl:text>
- </xsl:if>
- <!-- Always output the verse -->
- <xsl:choose>
- <xsl:when test="$VLine = 'true'">
- <div class="l"><a name="{@osisID}"><xsl:call-template name="versenum"/></a><xsl:apply-templates/></div>
- </xsl:when>
- <xsl:otherwise>
- <span class="interlinear"><xsl:call-template name="versenum"/><xsl:apply-templates/></span>
- <!-- Follow the verse with an extra space -->
- <!-- when they don't start on lines to themselves -->
- <xsl:text> </xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="verse[not(@eID)]" mode="jesus">
- <!-- If the verse doesn't start on its own line and -->
- <!-- the verse is not the first verse of a set of siblings, -->
- <!-- output an extra space. -->
- <xsl:if test="$VLine = 'false' and preceding-sibling::*[local-name() = 'verse']">
- <xsl:text> </xsl:text>
- </xsl:if>
- <xsl:variable name="title" select=".//title"/>
- <xsl:if test="string-length($title) > 0">
- <h3 class="heading"><xsl:value-of select="$title"/></h3>
- </xsl:if>
- <!-- Handle the KJV paragraph marker. -->
- <xsl:if test="milestone[@type = 'x-p']"><br/><br/></xsl:if>
- <!-- Always output the verse -->
- <xsl:choose>
- <xsl:when test="$VLine = 'true'">
- <div class="l"><a name="{@osisID}"><xsl:call-template name="versenum"/></a><xsl:apply-templates mode="jesus"/></div>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="versenum"/><xsl:apply-templates mode="jesus"/>
- <!-- Follow the verse with an extra space -->
- <!-- when they don't start on lines to themselves -->
- <xsl:text> </xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="verse" mode="print-notes">
- <xsl:if test=".//note[not(@type) or not(@type = 'x-strongsMarkup')]">
- <xsl:variable name="passage" select="jsword:getValidKey($keyf, @osisID)"/>
- <a href="#{substring-before(concat(@osisID, ' '), ' ')}">
- <xsl:value-of select="jsword:getName($passage)"/>
- </a>
- <xsl:apply-templates select=".//note" mode="print-notes" />
- <div><xsl:text> </xsl:text></div>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="versenum">
- <!-- Are verse numbers wanted? -->
- <xsl:if test="$NoVNum = 'false'">
- <!-- An osisID can be a space separated list of them -->
- <xsl:variable name="firstOsisID" select="substring-before(concat(@osisID, ' '), ' ')"/>
- <xsl:variable name="book" select="substring-before($firstOsisID, '.')"/>
- <xsl:variable name="chapter" select="jsword:shape($shaper, substring-before(substring-after($firstOsisID, '.'), '.'))"/>
- <!-- If n is present use it for the number -->
- <xsl:variable name="verse">
- <xsl:choose>
- <xsl:when test="@n">
- <xsl:value-of select="jsword:shape($shaper, string(@n))"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="jsword:shape($shaper, substring-after(substring-after($firstOsisID, '.'), '.'))"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="versenum">
- <xsl:choose>
- <xsl:when test="$BCVNum = 'true'">
- <xsl:variable name="passage" select="jsword:getValidKey($keyf, @osisID)"/>
- <xsl:value-of select="jsword:getName($passage)"/>
- </xsl:when>
- <xsl:when test="$CVNum = 'true'">
- <xsl:value-of select="concat($chapter, ' : ', $verse)"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$verse"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <!--
- == Surround versenum with dup
- -->
- <xsl:choose>
- <xsl:when test="$TinyVNum = 'true' and $Notes = 'true'">
- <span class="w"><a name="{@osisID}"><span class="verseNumber"><xsl:value-of select="$versenum"/></span></a></span>
- </xsl:when>
- <xsl:when test="$TinyVNum = 'true' and $Notes = 'false'">
- <span class="w"><span class="verseNumber"><xsl:value-of select="$versenum"/></span></span>
- </xsl:when>
- <xsl:when test="$TinyVNum = 'false' and $Notes = 'true'">
- <a name="{@osisID}">(<xsl:value-of select="$versenum"/>)</a>
- <xsl:text> </xsl:text>
- </xsl:when>
- <xsl:otherwise>
- (<xsl:value-of select="$versenum"/>)
- <xsl:text> </xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- <xsl:if test="$VNum = 'false' and $Notes = 'true'">
- <a name="{@osisID}"></a>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="a">
- <a href="{@href}"><xsl:apply-templates/></a>
- </xsl:template>
-
- <xsl:template match="a" mode="jesus">
- <a href="{@href}"><xsl:apply-templates mode="jesus"/></a>
- </xsl:template>
-
- <!--=======================================================================-->
- <!-- When we encounter a note, we merely output a link to the note. -->
- <xsl:template match="note[@type = 'x-strongsMarkup']"/>
- <xsl:template match="note[@type = 'x-strongsMarkup']" mode="jesus"/>
- <xsl:template match="note[@type = 'x-strongsMarkup']" mode="print-notes"/>
-
- <xsl:template match="note">
- <xsl:if test="$Notes = 'true'">
- <!-- If there is a following sibling that is a note, emit a separator -->
- <xsl:variable name="siblings" select="../child::node()"/>
- <xsl:variable name="next-position" select="position() + 1"/>
- <xsl:choose>
- <xsl:when test="name($siblings[$next-position]) = 'note'">
- <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a>, </sup>
- </xsl:when>
- <xsl:otherwise>
- <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a></sup>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="note" mode="jesus">
- <xsl:if test="$Notes = 'true'">
- <!-- If there is a following sibling that is a note, emit a separator -->
- <xsl:variable name="siblings" select="../child::node()"/>
- <xsl:variable name="next-position" select="position() + 1"/>
- <xsl:choose>
- <xsl:when test="$siblings[$next-position] and name($siblings[$next-position]) = 'note'">
- <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a>, </sup>
- </xsl:when>
- <xsl:otherwise>
- <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a></sup>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="note" mode="print-notes">
- <div class="margin">
- <strong><xsl:call-template name="generateNoteXref"/></strong>
- <a name="note-{generate-id(.)}">
- <xsl:text> </xsl:text>
- </a>
- <xsl:apply-templates/>
- </div>
- </xsl:template>
-
- <!--
- == If the n attribute is present then use that for the cross ref otherwise create a letter.
- == Note: numbering restarts with each verse.
- -->
- <xsl:template name="generateNoteXref">
- <xsl:choose>
- <xsl:when test="@n">
- <xsl:value-of select="@n"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:number level="any" from="/osis//verse" format="a"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="p">
- <p><xsl:apply-templates/></p>
- </xsl:template>
-
- <xsl:template match="p" mode="jesus">
- <p><xsl:apply-templates mode="jesus"/></p>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="p" mode="print-notes">
- <!-- FIXME: This ignores text in the note. -->
- <!-- don't put para's in notes -->
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="w">
- <!-- Output the content followed by all the lemmas and then all the morphs. -->
- <xsl:variable name="innerWordText"><xsl:apply-templates/></xsl:variable>
- <xsl:variable name="isNextSiblingText" select="following-sibling::*[1]/text() = ''" />
- <xsl:variable name="nextNodeCharClass" select="''" />
- <xsl:if test="following-sibling::*[1]/text() != ''">
- <xsl:variable name="nextNodeCharClass" select="'punctuNext'" />
- </xsl:if>
- <span class="w">
- <span class="text">
- <xsl:choose>
- <xsl:when test="not(normalize-space($innerWordText))"> </xsl:when>
- <xsl:otherwise><xsl:value-of select="$innerWordText" /></xsl:otherwise>
- </xsl:choose></span>
- <xsl:if test="$StrongsNumbers = 'true' and (starts-with(@lemma, 'x-Strongs:') or starts-with(@lemma, 'strong:'))">
- <xsl:call-template name="lemma">
- <xsl:with-param name="lemma" select="@lemma"/>
- </xsl:call-template>
- </xsl:if>
- <xsl:if test="$Morph = 'true' and (starts-with(@morph, 'x-Robinson:') or starts-with(@morph, 'robinson:'))">
- <xsl:call-template name="morph">
- <xsl:with-param name="morph" select="@morph"/>
- </xsl:call-template>
- </xsl:if>
- <xsl:if test="$StrongsNumbers = 'true' and starts-with(@lemma, 'lemma.Strong:')">
- <xsl:call-template name="lemma">
- <xsl:with-param name="lemma" select="@lemma"/>
- </xsl:call-template>
- </xsl:if>
- <xsl:if test="$Interlinear = 'true'">
- <xsl:call-template name="interlinear">
- <xsl:with-param name="lemma" select="@lemma" />
- <xsl:with-param name="morph" select="@morph" />
- <xsl:with-param name="osisID" select="../@osisID" />
- </xsl:call-template>
- </xsl:if>
-
- <!--
- except when followed by a text node or non-printing node.
- This is true whether the href is output or not.
- -->
- <xsl:variable name="siblings" select="../child::node()"/>
- <xsl:variable name="next-position" select="position() + 1"/>
- <xsl:if test="$siblings[$next-position] and name($siblings[$next-position]) != ''">
- <xsl:text> </xsl:text>
- </xsl:if>
- </span>
- </xsl:template>
-
- <xsl:template match="w" mode="jesus">
- <!-- Output the content followed by all the lemmas and then all the morphs. -->
- <xsl:apply-templates mode="jesus"/>
- <xsl:if test="$StrongsNumbers = 'true' and (starts-with(@lemma, 'x-Strongs:') or starts-with(@lemma, 'strong:'))">
- <xsl:call-template name="lemma">
- <xsl:with-param name="lemma" select="@lemma"/>
- </xsl:call-template>
- </xsl:if>
- <xsl:if test="$Morph = 'true' and (starts-with(@morph, 'x-Robinson:') or starts-with(@morph, 'robinson:'))">
- <xsl:call-template name="morph">
- <xsl:with-param name="morph" select="@morph"/>
- </xsl:call-template>
- </xsl:if>
- <!--
- except when followed by a text node or non-printing node.
- This is true whether the href is output or not.
- -->
- <xsl:variable name="siblings" select="../child::node()"/>
- <xsl:variable name="next-position" select="position() + 1"/>
- <xsl:if test="$siblings[$next-position] and name($siblings[$next-position]) != ''">
- <xsl:text> </xsl:text>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="lemma">
- <xsl:param name="lemma"/>
- <xsl:param name="part" select="0"/>
- <xsl:param name="className" />
- <xsl:param name="finalText" />
-
- <xsl:variable name="orig-lemma" select="substring-after($lemma, ':')"/>
- <xsl:variable name="protocol">
- <xsl:choose>
- <xsl:when test="substring($orig-lemma, 1, 1) = 'H'">
- <xsl:value-of select="$hebrew.def.protocol"/>
- </xsl:when>
- <xsl:when test="substring($orig-lemma, 1, 1) = 'G'">
- <xsl:value-of select="$greek.def.protocol"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$lex.def.protocol"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="separator">
- <xsl:choose>
- <xsl:when test="contains($orig-lemma, '|') ">
- <xsl:value-of select="'|'"/>
- </xsl:when>
- <xsl:when test="contains($orig-lemma, ' ')">
- <xsl:value-of select="' '"/>
- </xsl:when>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="sub">
- <xsl:choose>
- <xsl:when test="$separator != '' and $part = '0'">
- <xsl:value-of select="$part + 1"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$part"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <!-- TODO, we change this and put a condition above to determine whether we chop off from 1, or 2 -->
- <xsl:when test="$protocol = $lex.def.protocol">
- <font class="lex">[<xsl:value-of select="$orig-lemma"/>]</font>
- </xsl:when>
- <xsl:when test="$separator = ''">
- <span class="strongs {$className} {$orig-lemma}"><xsl:value-of select="concat($finalText, ' ', format-number(substring($orig-lemma, 2), '#'))" />
- </span>
- </xsl:when>
- <xsl:otherwise>
- <xsl:variable name="processedLemma" select="substring-before($orig-lemma, $separator)" />
- <xsl:call-template name="lemma">
- <xsl:with-param name="lemma" select="substring-after($lemma, $separator)"/>
- <xsl:with-param name="className" select="concat($className, $processedLemma)" />
- <xsl:with-param name="finalText" select="concat($finalText, ' ', format-number(substring($processedLemma,2),'#'))" />
- <xsl:with-param name="part">
- <xsl:choose>
- <xsl:when test="$sub">
- <xsl:value-of select="$sub + 1"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="1"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="morph">
- <xsl:param name="morph"/>
- <xsl:param name="part" select="0"/>
- <xsl:variable name="orig-work" select="substring-before($morph, ':')"/>
- <xsl:variable name="orig-morph" select="substring-after($morph, ':')"/>
- <xsl:variable name="protocol">
- <xsl:choose>
- <xsl:when test="starts-with($orig-work, 'x-Robinson') or starts-with($orig-work, 'robinson')">
- <xsl:value-of select="$greek.morph.protocol"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$hebrew.morph.protocol"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="separator">
- <xsl:choose>
- <xsl:when test="contains($orig-morph, '|')">
- <xsl:value-of select="'|'"/>
- </xsl:when>
- <xsl:when test="contains($orig-morph, ' ')">
- <xsl:value-of select="' '"/>
- </xsl:when>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="sub">
- <xsl:choose>
- <xsl:when test="$separator != '' and $part = '0'">
- <xsl:value-of select="$part + 1"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$part"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$separator = ''">
- <!-- <sub class="morph"><a href="{$protocol}{$orig-morph}">M<xsl:number level="any" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a></sub> -->
- <sub class="morph"><a href="{$protocol}{$orig-morph}"><xsl:value-of select="$orig-morph"/></a></sub>
- </xsl:when>
- <xsl:otherwise>
- <!-- <sub class="morph"><a href="{$protocol}{substring-before($orig-morph, $separator)}">M<xsl:number level="single" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a>, </sub> -->
- <sub class="morph"><a href="{$protocol}{substring-before($orig-morph, $separator)}"><xsl:value-of select="substring-before($orig-morph, $separator)"/></a>, </sub>
- <xsl:call-template name="morph">
- <xsl:with-param name="morph" select="substring-after($morph, $separator)"/>
- <xsl:with-param name="part">
- <xsl:choose>
- <xsl:when test="$sub">
- <xsl:value-of select="$sub + 1"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="1"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="interlinear">
- <xsl:param name="lemma" select="''"/>
- <xsl:param name="morph" select="''"/>
- <xsl:param name="osisID" />
- <xsl:variable name="interlinearWord" select="jsword:getWord($interlinearProvider, $osisID, $lemma, $morph)"/>
- <xsl:choose>
- <xsl:when test="normalize-space($interlinearWord) = ''" > </xsl:when>
- <xsl:otherwise><span class="interlinearText"><xsl:value-of select="$interlinearWord"/></span></xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
-
- <!--=======================================================================-->
- <xsl:template match="seg">
- <xsl:choose>
- <xsl:when test="starts-with(@type, 'color:')">
- <font color="{substring-before(substring-after(@type, 'color: '), ';')}"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="starts-with(@type, 'font-size:')">
- <font size="{substring-before(substring-after(@type, 'font-size: '), ';')}"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="@type = 'x-variant'">
- <xsl:if test="@subType = 'x-class-1'">
- <xsl:apply-templates/>
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="seg" mode="jesus">
- <xsl:choose>
- <xsl:when test="starts-with(@type, 'color:')">
- <font color="{substring-before(substring-after(@type, 'color: '), ';')}"><xsl:apply-templates mode="jesus"/></font>
- </xsl:when>
- <xsl:when test="starts-with(@type, 'font-size:')">
- <font size="{substring-before(substring-after(@type, 'font-size: '), ';')}"><xsl:apply-templates mode="jesus"/></font>
- </xsl:when>
- <xsl:when test="@type = 'x-variant'">
- <xsl:if test="@subType = 'x-class:1'">
- <xsl:apply-templates mode="jesus"/>
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates mode="jesus"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!--=======================================================================-->
- <!-- expansion is OSIS, expan is TEI -->
- <xsl:template match="abbr">
- <font class="abbr">
- <xsl:if test="@expansion">
- <xsl:attribute name="title">
- <xsl:value-of select="@expansion"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="@expan">
- <xsl:attribute name="title">
- <xsl:value-of select="@expan"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:apply-templates/>
- </font>
- </xsl:template>
-
- <xsl:template match="abbr" mode="jesus">
- <font class="abbr">
- <xsl:if test="@expansion">
- <xsl:attribute name="title">
- <xsl:value-of select="@expansion"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="@expan">
- <xsl:attribute name="title">
- <xsl:value-of select="@expan"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:apply-templates mode="jesus"/>
- </font>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="speaker[@who = 'Jesus']">
- <font class="jesus"><xsl:apply-templates mode="jesus"/></font>
- </xsl:template>
-
- <xsl:template match="speaker">
- <font class="speech"><xsl:apply-templates/></font>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="title[@subType ='x-preverse' or @subtype = 'x-preverse']">
- <!-- Done by a line in [verse]
- <h3 class="heading">
- <xsl:apply-templates/>
- </h3>
- -->
- </xsl:template>
-
- <xsl:template match="title[@subType ='x-preverse' or @subtype = 'x-preverse']" mode="jesus">
- <!-- Done by a line in [verse]
- <h3 class="heading">
- <xsl:apply-templates/>
- </h3>
- -->
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="title[@level]">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <xsl:choose>
- <xsl:when test="@level = '1'">
- <h1 class="level"><xsl:apply-templates/></h1>
- </xsl:when>
- <xsl:when test="@level = '2'">
- <h2 class="level"><xsl:apply-templates/></h2>
- </xsl:when>
- <xsl:when test="@level = '3'">
- <h3 class="level"><xsl:apply-templates/></h3>
- </xsl:when>
- <xsl:when test="@level = '4'">
- <h4 class="level"><xsl:apply-templates/></h4>
- </xsl:when>
- <xsl:when test="@level = '5'">
- <h5 class="level"><xsl:apply-templates/></h5>
- </xsl:when>
- <xsl:otherwise>
- <h6 class="level"><xsl:apply-templates/></h6>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="title[@level]" mode="jesus">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <xsl:choose>
- <xsl:when test="@level = '1'">
- <h1 class="level"><xsl:apply-templates/></h1>
- </xsl:when>
- <xsl:when test="@level = '2'">
- <h2 class="level"><xsl:apply-templates/></h2>
- </xsl:when>
- <xsl:when test="@level = '3'">
- <h3 class="level"><xsl:apply-templates/></h3>
- </xsl:when>
- <xsl:when test="@level = '4'">
- <h4 class="level"><xsl:apply-templates/></h4>
- </xsl:when>
- <xsl:when test="@level = '5'">
- <h5 class="level"><xsl:apply-templates/></h5>
- </xsl:when>
- <xsl:otherwise>
- <h6 class="level"><xsl:apply-templates/></h6>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="title">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <h2 class="heading"><xsl:apply-templates/></h2>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="title" mode="jesus">
- <!-- Always show canonical titles or if headings is turned on -->
- <xsl:if test="@canonical = 'true' or $Headings = 'true'">
- <h2 class="heading"><xsl:apply-templates/></h2>
- </xsl:if>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="reference">
- <xsl:choose>
- <xsl:when test="$XRef = 'true'">
- <a href="bible://{@osisRef}"><xsl:apply-templates/></a>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="reference" mode="jesus">
- <xsl:choose>
- <xsl:when test="$XRef = 'true'">
- <a href="bible://{@osisRef}"><xsl:apply-templates mode="jesus"/></a>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates mode="jesus"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!--=======================================================================-->
- <xsl:template match="caption">
- <div class="caption"><xsl:apply-templates/></div>
- </xsl:template>
-
- <xsl:template match="caption" mode="jesus">
- <div class="caption"><xsl:apply-templates/></div>
- </xsl:template>
-
- <xsl:template match="catchWord">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="catchWord" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!--
- <cell> is handled shortly after <table> below and thus does not appear
- here.
- -->
-
- <xsl:template match="closer">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="closer" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <xsl:template match="date">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="date" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <xsl:template match="divineName">
- <xsl:apply-templates mode="small-caps"/>
- </xsl:template>
-
- <xsl:template match="divineName" mode="jesus">
- <xsl:apply-templates mode="small-caps"/>
- </xsl:template>
-
- <xsl:template match="figure">
- <div class="figure">
- <xsl:choose>
- <xsl:when test="starts-with(@src, '/')">
- <img src="{concat($baseURL, @src)}"/> <!-- FIXME: Not necessarily an image... -->
- </xsl:when>
- <xsl:otherwise>
- <img src="{concat($baseURL, '/', @src)}"/> <!-- FIXME: Not necessarily an image... -->
- </xsl:otherwise>
- </xsl:choose>
- <xsl:apply-templates/>
- </div>
- </xsl:template>
-
- <xsl:template match="figure" mode="jesus">
- <div class="figure">
- <xsl:choose>
- <xsl:when test="starts-with(@src, '/')">
- <img src="{concat($baseURL, @src)}"/> <!-- FIXME: Not necessarily an image... -->
- </xsl:when>
- <xsl:otherwise>
- <img src="{concat($baseURL, '/', @src)}"/> <!-- FIXME: Not necessarily an image... -->
- </xsl:otherwise>
- </xsl:choose>
- <xsl:apply-templates mode="jesus"/>
- </div>
- </xsl:template>
-
- <xsl:template match="foreign">
- <em class="foreign"><xsl:apply-templates/></em>
- </xsl:template>
-
- <xsl:template match="foreign" mode="jesus">
- <em class="foreign"><xsl:apply-templates mode="jesus"/></em>
- </xsl:template>
-
- <!-- This is a subheading. -->
- <xsl:template match="head//head">
- <h5 class="head"><xsl:apply-templates/></h5>
- </xsl:template>
-
- <!-- This is a top-level heading. -->
- <xsl:template match="head">
- <h4 class="head"><xsl:apply-templates/></h4>
- </xsl:template>
-
- <xsl:template match="index">
- <a name="index{@id}" class="index"/>
- </xsl:template>
-
- <xsl:template match="inscription">
- <xsl:apply-templates mode="small-caps"/>
- </xsl:template>
-
- <xsl:template match="inscription" mode="jesus">
- <xsl:apply-templates mode="small-caps"/>
- </xsl:template>
-
- <xsl:template match="item">
- <li class="item"><xsl:apply-templates/></li>
- </xsl:template>
-
- <xsl:template match="item" mode="jesus">
- <li class="item"><xsl:apply-templates mode="jesus"/></li>
- </xsl:template>
-
- <!--
- <item> and <label> are covered by <list> below and so do not appear here.
- -->
-
- <xsl:template match="lg">
- <div class="lg"><xsl:apply-templates/></div>
- </xsl:template>
-
- <xsl:template match="lg" mode="jesus">
- <div class="lg"><xsl:apply-templates mode="jesus"/></div>
- </xsl:template>
-
- <xsl:template match="lg[@sID or @eID]"/>
- <xsl:template match="lg[@sID or @eID]" mode="jesus"/>
-
- <xsl:template match="l[@sID]"/>
- <xsl:template match="l[@sID]" mode="jesus"/>
-
- <xsl:template match="l[@eID]"><br/></xsl:template>
- <xsl:template match="l[@eID]" mode="jesus"><br/></xsl:template>
-
- <xsl:template match="l">
- <xsl:apply-templates/><br/>
- </xsl:template>
-
- <xsl:template match="l" mode="jesus">
- <xsl:apply-templates mode="jesus"/><br/>
- </xsl:template>
-
- <!-- While a BR is a break, if it is immediately followed by punctuation,
- indenting this rule can introduce whitespace.
- -->
- <xsl:template match="lb"><br/></xsl:template>
- <xsl:template match="lb" mode="jesus"><br/></xsl:template>
-
- <xsl:template match="list">
- <xsl:choose>
- <xsl:when test="label">
- <!-- If there are <label>s in the list, it's a <dl>. -->
- <dl class="list">
- <xsl:for-each select="node()">
- <xsl:choose>
- <xsl:when test="self::label">
- <dt class="label"><xsl:apply-templates/></dt>
- </xsl:when>
- <xsl:when test="self::item">
- <dd class="item"><xsl:apply-templates/></dd>
- </xsl:when>
- <xsl:when test="self::list">
- <dd class="list-wrapper"><xsl:apply-templates select="."/></dd>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </dl>
- </xsl:when>
-
- <xsl:otherwise>
- <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
- <ul class="list">
- <xsl:for-each select="node()">
- <xsl:choose>
- <xsl:when test="self::item">
- <li class="item"><xsl:apply-templates/></li>
- </xsl:when>
- <xsl:when test="self::list">
- <li class="list-wrapper"><xsl:apply-templates select="."/></li>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </ul>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
-
- <xsl:template match="list" mode="jesus">
- <xsl:choose>
- <xsl:when test="label">
- <!-- If there are <label>s in the list, it's a <dl>. -->
- <dl class="list">
- <xsl:for-each select="node()">
- <xsl:choose>
- <xsl:when test="self::label">
- <dt class="label"><xsl:apply-templates mode="jesus"/></dt>
- </xsl:when>
- <xsl:when test="self::item">
- <dd class="item"><xsl:apply-templates mode="jesus"/></dd>
- </xsl:when>
- <xsl:when test="self::list">
- <dd class="list-wrapper"><xsl:apply-templates select="." mode="jesus"/></dd>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates mode="jesus"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </dl>
- </xsl:when>
-
- <xsl:otherwise>
- <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
- <ul class="list">
- <xsl:for-each select="node()">
- <xsl:choose>
- <xsl:when test="self::item">
- <li class="item"><xsl:apply-templates mode="jesus"/></li>
- </xsl:when>
- <xsl:when test="self::list">
- <li class="list-wrapper"><xsl:apply-templates select="." mode="jesus"/></li>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates mode="jesus"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </ul>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="mentioned">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="mentioned" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!-- Milestones represent characteristics of the original manuscript.
- == that are being preserved. For this reason, most are ignored.
- ==
- == The defined types are:
- == column Marks the end of a column where there is a multi-column display.
- == footer Marks the footer region of a page.
- == halfLine Used to mark half-line units if not otherwise encoded.
- == header Marks the header region of a page.
- == line Marks line breaks, particularly important in recording appearance of an original text, such as a manuscript.
- == pb Marks a page break in a text.
- == screen Marks a preferred place for breaks in an on-screen rendering of the text.
- == cQuote Marks the location of a continuation quote mark, with marker containing the publishers mark.
- -->
- <!-- This is used by the KJV for paragraph markers. -->
- <xsl:template match="milestone[@type = 'x-p']"><xsl:text> </xsl:text><xsl:value-of select="@marker"/><xsl:text> </xsl:text></xsl:template>
- <xsl:template match="milestone[@type = 'x-p']" mode="jesus"><xsl:text> </xsl:text><xsl:value-of select="@marker"/><xsl:text> </xsl:text></xsl:template>
-
- <xsl:template match="milestone[@type = 'cQuote']">
- <xsl:value-of select="@marker"/>
- </xsl:template>
-
- <xsl:template match="milestone[@type = 'cQuote']" mode="jesus">
- <xsl:value-of select="@marker"/>
- </xsl:template>
-
- <xsl:template match="milestone[@type = 'line']"><br/></xsl:template>
-
- <xsl:template match="milestone[@type = 'line']" mode="jesus"><br/></xsl:template>
-
- <!--
- == Milestone start and end are deprecated.
- == At this point we expect them to not be in the document.
- == These have been replace with milestoneable elements.
- -->
- <xsl:template match="milestoneStart"/>
- <xsl:template match="milestoneEnd"/>
-
- <xsl:template match="name">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="name" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!-- If there is a milestoned q then just output a quotation mark -->
- <xsl:template match="q[@sID or @eID]">
- <xsl:choose>
- <xsl:when test="@marker"><xsl:value-of select="@marker"/></xsl:when>
- <!-- The chosen mark should be based on the work's author's locale. -->
- <xsl:otherwise>"</xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="q[@sID or @eID]" mode="jesus">
- <xsl:choose>
- <xsl:when test="@marker"><xsl:value-of select="@marker"/></xsl:when>
- <!-- The chosen mark should be based on the work's author's locale. -->
- <xsl:otherwise>"</xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="q[@who = 'Jesus']">
- <font class="jesus"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></font>
- </xsl:template>
-
- <xsl:template match="q[@type = 'blockquote']">
- <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/></blockquote>
- </xsl:template>
-
- <xsl:template match="q[@type = 'blockquote']" mode="jesus">
- <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></blockquote>
- </xsl:template>
-
- <xsl:template match="q[@type = 'citation']">
- <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/></blockquote>
- </xsl:template>
-
- <xsl:template match="q[@type = 'citation']" mode="jesus">
- <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></blockquote>
- </xsl:template>
-
- <xsl:template match="q[@type = 'embedded']">
- <xsl:choose>
- <xsl:when test="@marker">
- <xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/>
- </xsl:when>
- <xsl:otherwise>
- <quote class="q"><xsl:apply-templates/></quote>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="q[@type = 'embedded']" mode="jesus">
- <xsl:choose>
- <xsl:when test="@marker">
- <xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/>
- </xsl:when>
- <xsl:otherwise>
- <quote class="q"><xsl:apply-templates/></quote>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- An alternate reading. -->
- <xsl:template match="rdg">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="rdg" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <!--
- <row> is handled near <table> below and so does not appear here.
- -->
-
- <xsl:template match="salute">
- <xsl:apply-templates/>
- </xsl:template>
-
- <!-- Avoid adding whitespace -->
- <xsl:template match="salute" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <xsl:template match="signed">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="signed" mode="jesus">
- <xsl:apply-templates mode="jesus"/>
- </xsl:template>
-
- <xsl:template match="speech">
- <div class="speech"><xsl:apply-templates/></div>
- </xsl:template>
-
- <xsl:template match="speech" mode="jesus">
- <div class="speech"><xsl:apply-templates mode="jesus"/></div>
- </xsl:template>
-
- <xsl:template match="table">
- <table class="table">
- <xsl:copy-of select="@rows|@cols"/>
- <xsl:if test="head">
- <thead class="head"><xsl:apply-templates select="head"/></thead>
- </xsl:if>
- <tbody><xsl:apply-templates select="row"/></tbody>
- </table>
- </xsl:template>
-
- <xsl:template match="row">
- <tr class="row"><xsl:apply-templates/></tr>
- </xsl:template>
-
- <xsl:template match="cell">
- <xsl:variable name="element-name">
- <xsl:choose>
- <xsl:when test="@role = 'label'">
- <xsl:text>th</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>td</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="cell-direction">
- <xsl:if test="@xml:lang">
- <xsl:call-template name="getDirection">
- <xsl:with-param name="lang"><xsl:value-of select="@xml:lang"/></xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:variable>
- <xsl:element name="{$element-name}">
- <xsl:attribute name="class">cell</xsl:attribute>
- <xsl:attribute name="valign">top</xsl:attribute>
- <xsl:if test="@xml:lang">
- <xsl:attribute name="dir">
- <xsl:value-of select="$cell-direction"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="$cell-direction = 'rtl'">
- <xsl:attribute name="align">
- <xsl:value-of select="'right'"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="@rows">
- <xsl:attribute name="rowspan">
- <xsl:value-of select="@rows"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:if test="@cols">
- <xsl:attribute name="colspan">
- <xsl:value-of select="@cols"/>
- </xsl:attribute>
- </xsl:if>
- <!-- hack alert -->
- <xsl:choose>
- <xsl:when test="$cell-direction = 'rtl'">
- <xsl:text>‫</xsl:text><xsl:apply-templates/><xsl:text>‬</xsl:text>
- </xsl:when>
- <xsl:when test="$cell-direction = 'ltr'">
- <xsl:text>‪</xsl:text><xsl:apply-templates/><xsl:text>‬</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:element>
- </xsl:template>
-
- <xsl:template match="transChange">
- <span><em><xsl:apply-templates/></em></span>
- </xsl:template>
- <xsl:template match="transChange" mode="jesus">
- <span class="w"><em><xsl:apply-templates/></em></span>
- </xsl:template>
-
- <!-- @type is OSIS, @rend is TEI -->
- <xsl:template match="hi">
- <xsl:variable name="style">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@rend"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$style = 'acrostic'">
- <xsl:apply-templates/>
- </xsl:when>
- <xsl:when test="$style = 'bold'">
- <strong><xsl:apply-templates/></strong>
- </xsl:when>
- <xsl:when test="$style = 'emphasis'">
- <em><xsl:apply-templates/></em>
- </xsl:when>
- <xsl:when test="$style = 'illuminated'">
- <strong><em><xsl:apply-templates/></em></strong>
- </xsl:when>
- <xsl:when test="$style = 'italic'">
- <em><xsl:apply-templates/></em>
- </xsl:when>
- <xsl:when test="$style = 'line-through'">
- <font class="strike"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="$style = 'normal'">
- <font class="normal"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="$style = 'small-caps'">
- <font class="small-caps"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="$style = 'sub'">
- <sub><xsl:apply-templates/></sub>
- </xsl:when>
- <xsl:when test="$style = 'super'">
- <sup><xsl:apply-templates/></sup>
- </xsl:when>
- <xsl:when test="$style = 'underline'">
- <u><xsl:apply-templates/></u>
- </xsl:when>
- <xsl:when test="$style = 'x-caps'">
- <font class="caps"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="hi" mode="jesus">
- <xsl:variable name="style">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@rend"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$style = 'acrostic'">
- <xsl:apply-templates/>
- </xsl:when>
- <xsl:when test="$style = 'bold'">
- <strong><xsl:apply-templates/></strong>
- </xsl:when>
- <xsl:when test="$style = 'emphasis'">
- <em><xsl:apply-templates/></em>
- </xsl:when>
- <xsl:when test="$style = 'illuminated'">
- <strong><em><xsl:apply-templates/></em></strong>
- </xsl:when>
- <xsl:when test="$style = 'italic'">
- <em><xsl:apply-templates/></em>
- </xsl:when>
- <xsl:when test="$style = 'line-through'">
- <font class="strike"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="$style = 'normal'">
- <font class="normal"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="$style = 'small-caps'">
- <font class="small-caps"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:when test="$style = 'sub'">
- <sub><xsl:apply-templates/></sub>
- </xsl:when>
- <xsl:when test="$style = 'super'">
- <sup><xsl:apply-templates/></sup>
- </xsl:when>
- <xsl:when test="$style = 'underline'">
- <u><xsl:apply-templates/></u>
- </xsl:when>
- <xsl:when test="$style = 'x-caps'">
- <font class="caps"><xsl:apply-templates/></font>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!--
- The following elements are actually TEI and there is some expectation
- that these will make it into OSIS.
- -->
- <xsl:template match="superentry">
- <!-- output each preverse element in turn -->
- <xsl:for-each select="entry|entryFree">
- <xsl:apply-templates/><br/><br/>
- </xsl:for-each>
- </xsl:template>
-
- <xsl:template match="entry">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="entryFree">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="form">
- <xsl:apply-templates/><br/>
- </xsl:template>
-
- <xsl:template match="orth">
- <font class="orth"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="pron">
- <font class="pron"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="etym">
- <font class="etym"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="def">
- <font class="def"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="usg">
- <font class="usg"><xsl:apply-templates/></font>
- </xsl:template>
-
- <xsl:template match="@xml:lang">
- <xsl:variable name="dir">
- <xsl:if test="@xml:lang">
- <xsl:call-template name="getDirection">
- <xsl:with-param name="lang"><xsl:value-of select="@xml:lang"/></xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:variable>
- <xsl:if test="$dir">
- <xsl:attribute name="dir">
- <xsl:value-of select="$dir"/>
- </xsl:attribute>
- </xsl:if>
- </xsl:template>
-
- <!-- If the parent of the text is a verse then, we need to wrap in span. This applies
- to any punctuation really, since all other words should be contained in a W -->
- <xsl:template match="text()">
- <xsl:choose>
- <xsl:when test="name(..) = 'verse' and normalize-space(.) != ''"><span class="w"><span class="text"><xsl:value-of select="."/></span></span></xsl:when>
- <xsl:when test="normalize-space(.) != ''"><xsl:value-of select="."/></xsl:when>
- </xsl:choose>
- </xsl:template>
-
-
- <xsl:template match="text()" mode="small-caps">
- <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
- </xsl:template>
-
- <!--
- The direction is deduced from the xml:lang attribute and is assumed to be meaningful for those elements.
- Note: there is a bug that prevents dir=rtl from working.
- see: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4296022 and 4866977
- -->
- <xsl:template name="getDirection">
- <xsl:param name="lang"/>
- <xsl:choose>
- <xsl:when test="$lang = 'he' or $lang = 'ar' or $lang = 'fa' or $lang = 'ur' or $lang = 'syr'">
- <xsl:value-of select="'rtl'"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="'ltr'"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="string-replace-all">
- <xsl:param name="text" />
- <xsl:param name="replace" />
- <xsl:param name="by" />
- <xsl:choose>
- <xsl:when test="contains($text, $replace)">
- <xsl:value-of select="substring-before($text,$replace)" />
- <xsl:value-of select="$by" />
- <xsl:call-template name="string-replace-all">
- <xsl:with-param name="text" select="substring-after($text,$replace)" />
- <xsl:with-param name="replace" select="$replace" />
- <xsl:with-param name="by" select="$by" />
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$text" />
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-</xsl:stylesheet>
Added: trunk/step/step-core/src/main/resources/step.core.properties
===================================================================
--- trunk/step/step-core/src/main/resources/step.core.properties (rev 0)
+++ trunk/step/step-core/src/main/resources/step.core.properties 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,7 @@
+#list of installers in the format: host,package,catalog
+installer.1=www.crosswire.org,/ftpmirror/pub/sword/packages/rawzip,/ftpmirror/pub/sword/raw
+installer.2=ftp.bible.org,/sword/packages/rawzip,/sword/raw
+installer.3=www.crosswire.org,/ftpmirror/pub/sword/betapackages/rawzip,/ftpmirror/pub/sword/betaraw
+
+app.proxy.host=
+app.proxy.port=
Modified: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -2,14 +2,19 @@
import static com.tyndalehouse.step.core.models.LookupOption.INTERLINEAR;
+import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
+import java.util.List;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.BookData;
+import org.crosswire.jsword.book.BookException;
import org.crosswire.jsword.book.Books;
+import org.crosswire.jsword.passage.NoSuchKeyException;
import org.jdom.Document;
import org.jdom.Element;
+import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
@@ -28,32 +33,36 @@
*
*/
public class JSwordServiceImplTest {
- private final Logger logger = LoggerFactory.getLogger(getClass());
+ private static final Logger LOGGER = LoggerFactory.getLogger(JSwordServiceImplTest.class);
/**
* tests what happens when we select interlinear
*
- * @throws Exception an uncaught exception
+ * @throws NoSuchKeyException uncaught exceptions
+ * @throws BookException uncaught exception
+ * @throws IOException uncaught exception
+ * @throws JDOMException uncaught exception
+ *
*/
@Test
- public void testInterlinearTransformation() throws Exception {
+ public void testInterlinearTransformation() throws NoSuchKeyException, BookException, JDOMException, IOException {
final Book currentBook = Books.installed().getBook("KJV");
final BookData bookData = new BookData(currentBook, currentBook.getKey("Romans 1:1-3"));
final Element osisFragment = bookData.getOsisFragment();
final XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
- this.logger.debug(xmlOutputter.outputString(osisFragment));
+ LOGGER.debug(xmlOutputter.outputString(osisFragment));
// do the test
- final JSwordServiceImpl jsi = new JSwordServiceImpl();
- final ArrayList<LookupOption> options = new ArrayList<LookupOption>();
+ final JSwordServiceImpl jsi = new JSwordServiceImpl(null);
+ final List<LookupOption> options = new ArrayList<LookupOption>();
options.add(INTERLINEAR);
final String osisText = jsi.getOsisText("KJV", "Romans 1:1-3", options, "KJV");
final SAXBuilder sb = new SAXBuilder();
final Document d = sb.build(new StringReader(osisText));
- this.logger.debug("\n {}", xmlOutputter.outputString(d));
+ LOGGER.debug("\n {}", xmlOutputter.outputString(d));
Assert.assertTrue(osisText.contains("span"));
}
@@ -61,27 +70,30 @@
/**
* tests that the XSLT transformation is handled correctly
*
- * @throws Exception uncaught exception
+ * @throws BookException uncaught exception
+ * @throws NoSuchKeyException uncaught exception
+ * @throws IOException uncaught exception
+ * @throws JDOMException uncaught exception
*/
@Test
- public void testXslTransformation() throws Exception {
+ public void testXslTransformation() throws BookException, NoSuchKeyException, JDOMException, IOException {
final Book currentBook = Books.installed().getBook("KJV");
final BookData bookData = new BookData(currentBook, currentBook.getKey("Romans 1:4"));
final Element osisFragment = bookData.getOsisFragment();
final XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
- this.logger.debug(xmlOutputter.outputString(osisFragment));
+ LOGGER.debug(xmlOutputter.outputString(osisFragment));
// do the test
- final JSwordServiceImpl jsi = new JSwordServiceImpl();
- final ArrayList<LookupOption> options = new ArrayList<LookupOption>();
+ final JSwordServiceImpl jsi = new JSwordServiceImpl(null);
+ final List<LookupOption> options = new ArrayList<LookupOption>();
options.add(LookupOption.STRONG_NUMBERS);
final String osisText = jsi.getOsisText("KJV", "Romans 1:4", options, "");
final SAXBuilder sb = new SAXBuilder();
final Document d = sb.build(new StringReader(osisText));
- this.logger.debug("\n {}", xmlOutputter.outputString(d));
+ LOGGER.debug("\n {}", xmlOutputter.outputString(d));
Assert.assertTrue(osisText.contains("span"));
}
}
Modified: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/ModuleServiceImplTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/ModuleServiceImplTest.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/ModuleServiceImplTest.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -7,17 +7,22 @@
import org.junit.Test;
+/**
+ * A simple test for the module service
+ *
+ * @author Chris
+ *
+ */
public class ModuleServiceImplTest {
/**
* tests that different definitions references resolve to the right module by default
*/
@Test
public void testGetLookupModule() {
- final ModuleServiceImpl msi = new ModuleServiceImpl();
final Map<String, String> defaultModules = new HashMap<String, String>();
- msi.setDefaultModuleLexicons(defaultModules);
+ defaultModules.put("key:", "module");
+ final ModuleServiceImpl msi = new ModuleServiceImpl(defaultModules, null);
- defaultModules.put("key:", "module");
assertEquals("module", msi.getLookupModule("key:H2929"));
}
}
Modified: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/utils/StringConversionUtilsTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/utils/StringConversionUtilsTest.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/utils/StringConversionUtilsTest.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -5,7 +5,16 @@
import org.junit.Test;
+/**
+ * Tests the utility method for converting strings
+ *
+ * @author Chris
+ *
+ */
public class StringConversionUtilsTest {
+ /**
+ * tests that getAnyKey returns the right portion of the string for different keys
+ */
@Test
public void testGetAnyKey() {
assertEquals(getAnyKey("strong:H1"), "1");
Modified: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImplTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImplTest.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImplTest.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -4,6 +4,12 @@
import org.junit.Test;
+/**
+ * A simple test class to test to the provider
+ *
+ * @author Chris
+ *
+ */
public class InterlinearProviderImplTest {
/**
* this checks that when keyed with strong, morph and verse number, we can retrieve the word. We should be able to
Modified: trunk/step/step-parent/pom.xml
===================================================================
--- trunk/step/step-parent/pom.xml 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-parent/pom.xml 2010-12-19 11:27:36 UTC (rev 195)
@@ -18,28 +18,33 @@
<derby.version>10.5.3.0_1</derby.version>
<junit.version>4.8.2</junit.version>
+
+ <!-- jsword dependencies -->
<jsword.version>1.6.1-SNAPSHOT</jsword.version>
-
- <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
- <jackson-mapper-asl.version>1.5.3</jackson-mapper-asl.version>
+ <jdom.version>1.1</jdom.version>
+ <javatar.version>2.5</javatar.version>
+
+ <jackson-mapper-asl.version>1.6.2</jackson-mapper-asl.version>
<org.slf4j.version>1.6.1</org.slf4j.version>
<servlet-api.version>2.5</servlet-api.version>
<jsp-api.version>2.1</jsp-api.version>
<jstl.version>1.2</jstl.version>
<pjl-comp-filter.version>1.6.4</pjl-comp-filter.version>
+ <guice.version>2.1.8</guice.version>
+ <guice-servlet.version>2.9.1</guice-servlet.version>
+ <opencsv.version>2.1</opencsv.version>
+ <jetty.version>6.1.22</jetty.version>
<!-- Commons -->
<commons-beanutils.version>1.8.3</commons-beanutils.version>
<commons-lang.version>2.5</commons-lang.version>
-
-
+ <commons-collections.version>3.2.1</commons-collections.version>
<commons-configuration.version>1.6</commons-configuration.version>
-
<commons-dbcp.version>1.3</commons-dbcp.version>
<commons-io.version>1.4</commons-io.version>
<commons-dbutils.version>1.3</commons-dbutils.version>
- <jmock.version>2.5.1</jmock.version>
- <opencsv.version>2.1</opencsv.version>
+
+ <!-- testing dependencies -->
<mockito.version>1.8.5</mockito.version>
</properties>
@@ -56,7 +61,6 @@
<artifactId>step-core</artifactId>
<version>${project.version}</version>
</dependency>
-
<dependency>
<groupId>org.crosswire</groupId>
<artifactId>jsword</artifactId>
@@ -67,28 +71,17 @@
<artifactId>jsword-common</artifactId>
<version>${jsword.version}</version>
</dependency>
-
- <!-- Spring dependencies -->
<dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${org.springframework.version}</version>
- <exclusions>
- <!-- Exclude Commons Logging in favor of SLF4j -->
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
-
+ <groupId>javatar</groupId>
+ <artifactId>javatar</artifactId>
+ <version>${javatar.version}</version>
</dependency>
<dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${org.springframework.version}</version>
+ <groupId>org.jdom</groupId>
+ <artifactId>jdom</artifactId>
+ <version>${jdom.version}</version>
</dependency>
-
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
@@ -138,7 +131,35 @@
<version>${pjl-comp-filter.version}</version>
</dependency>
+ <!-- TODO build against google released artifacts -->
<dependency>
+ <groupId>com.jolira</groupId>
+ <artifactId>guice</artifactId>
+ <version>${guice.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.sonatype.sisu.inject</groupId>
+ <artifactId>guice-servlet</artifactId>
+ <version>${guice-servlet.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.restlet.jee</groupId>
+ <artifactId>org.restlet</artifactId>
+ <version>${restlet.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.restlet.jee</groupId>
+ <artifactId>org.restlet.ext.servlet</artifactId>
+ <version>${restlet.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.restlet.jee</groupId>
+ <artifactId>org.restlet.ext.json</artifactId>
+ <version>${restlet.version}</version>
+ </dependency>
+ <dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons-beanutils.version}</version>
@@ -150,12 +171,13 @@
<version>${commons-lang.version}</version>
</dependency>
-
- <!-- probably unnecessary for now <dependency> <groupId>org.tuckey</groupId>
- <artifactId>urlrewritefilter</artifactId> <version>3.1.0</version> </dependency> -->
-
-
<dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>${commons-collections.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
@@ -182,20 +204,6 @@
</dependency>
<dependency>
- <groupId>org.jmock</groupId>
- <artifactId>jmock</artifactId>
- <version>${jmock.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jmock</groupId>
- <artifactId>jmock-junit4</artifactId>
- <version>${jmock.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>${derby.version}</version>
@@ -222,6 +230,12 @@
</dependency>
<dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty</artifactId>
+ <version>${jetty.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
@@ -251,6 +265,8 @@
<version>2.5</version>
<configuration>
<junitArtifactName>junit:junit-dep</junitArtifactName>
+ <parallel>classes</parallel>
+ <threadCount>4</threadCount>
</configuration>
</plugin>
@@ -280,18 +296,19 @@
<wtpversion>2.0</wtpversion>
<additionalProjectnatures>
- <projectnature>com.google.gwt.eclipse.core.gwtNature</projectnature>
- <projectnature>com.google.gdt.eclipse.core.webAppNature</projectnature>
<projectnature>net.sourceforge.pmd.eclipse.plugin.pmdNature</projectnature>
<projectnature>net.sf.eclipsecs.core.CheckstyleNature</projectnature>
<projectnature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</projectnature>
+ <projectnature>org.maven.ide.eclipse.maven2Nature</projectnature>
+
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>net.sourceforge.pmd.eclipse.plugin.pmdBuilder</buildcommand>
<buildcommand>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</buildcommand>
<buildcommand>net.sf.eclipsecs.core.CheckstyleBuilder</buildcommand>
+ <buildcommand>org.maven.ide.eclipse.maven2Builder</buildcommand>
</additionalBuildcommands>
-
+
<additionalConfig>
<file>
<name>.settings/org.eclipse.jdt.core.prefs</name>
@@ -311,6 +328,10 @@
<location>/checkstyle/checkstyle.xml</location>
</file>
<file>
+ <name>.checkstyle.config.test.xml</name>
+ <location>/checkstyle/checkstyle.test.xml</location>
+ </file>
+ <file>
<name>.pmd</name>
<location>/eclipse/pmd.xml</location>
</file>
@@ -318,7 +339,10 @@
<name>.fbprefs</name>
<location>/eclipse/.fbprefs</location>
</file>
-
+ <file>
+ <name>.LICENSE.txt</name>
+ <location>/checkstyle/license.txt</location>
+ </file>
</additionalConfig>
</configuration>
<dependencies>
Modified: trunk/step/step-server/pom.xml
===================================================================
--- trunk/step/step-server/pom.xml 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-server/pom.xml 2010-12-19 11:27:36 UTC (rev 195)
@@ -8,7 +8,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
- <groupId>com.tyndalehouse</groupId>
+ <groupId>com.tyndalehouse.step</groupId>
<artifactId>step-server</artifactId>
<packaging>jar</packaging>
<name>STEP :: Server wrapper for local execution</name>
@@ -17,7 +17,35 @@
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
- <version>6.1.22</version>
+ <version>${jetty.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
</dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <archive>
+ <manifest>
+ <mainClass>com.tyndalehouse.step.server.StepServer</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
Modified: trunk/step/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java
===================================================================
--- trunk/step/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,50 +1,80 @@
package com.tyndalehouse.step.server;
-//import java.awt.Desktop;
import java.awt.Desktop;
+import java.io.IOException;
import java.net.URI;
import java.net.URL;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.xml.XmlConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
-public class StepServer {
+/**
+ * the main class that kicks off the application
+ *
+ * @author Chris
+ *
+ */
+public final class StepServer {
+ private static final Logger LOGGER = LoggerFactory.getLogger(StepServer.class);
/**
+ * hiding implementation
+ */
+ private StepServer() {
+ // hiding implementation
+ }
+
+ /**
* creates and configures the Jetty server
*
* @return the Server object if required to make modifications
- * @throws Exception any uncaught exceptions that should be logged before exiting
*/
- private Server start() throws Exception {
+ private Server start() {
final Server jetty = new Server();
- final URL jettyConfig = StepServer.class.getClassLoader().getResource("jetty.xml");
- final URL warURL = StepServer.class.getClassLoader().getResource("war");
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+ final URL jettyConfig = currentClassLoader.getResource("jetty.xml");
+ final URL warURL = currentClassLoader.getResource("war");
// configure jetty
- final XmlConfiguration configuration = new XmlConfiguration(jettyConfig);
- configuration.configure(jetty);
+ XmlConfiguration configuration;
+ try {
+ configuration = new XmlConfiguration(jettyConfig);
+ configuration.configure(jetty);
- // configure our web application
- jetty.setHandler(new WebAppContext(warURL.toExternalForm(), "/step-web"));
+ // configure our web application
+ jetty.setHandler(new WebAppContext(warURL.toExternalForm(), "/step-web"));
- // start the server
- jetty.start();
+ // start the server
+ jetty.start();
+ } catch (final SAXException e) {
+ LOGGER.error(e.getMessage(), e);
+ } catch (final IOException e) {
+ LOGGER.error(e.getMessage(), e);
+ // CHECKSTYLE:OFF
+ } catch (final Exception e) {
+ // CHECKSTYLE:ON
+ LOGGER.error(e.getMessage(), e);
+ }
return jetty;
}
/**
- * @param args
+ * @param args a list of unused arguments on the command line
*/
+ // CHECKSTYLE:OFF
public static void main(final String[] args) {
try {
- // TODO setup logger somewhere!
final StepServer ms = new StepServer();
ms.start();
Desktop.getDesktop().browse(new URI("http://localhost:8080/step-web"));
+
} catch (final Exception e) {
- e.printStackTrace();
+ LOGGER.debug(e.getMessage(), e);
}
}
+ // CHECKSTYLE:ON
}
Modified: trunk/step/step-web/pom.xml
===================================================================
--- trunk/step/step-web/pom.xml 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/pom.xml 2010-12-19 11:27:36 UTC (rev 195)
@@ -19,16 +19,8 @@
<dependency>
<groupId>com.tyndalehouse.step</groupId>
<artifactId>step-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
</dependency>
<dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- </dependency>
- <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</dependency>
@@ -65,17 +57,40 @@
<artifactId>jstl</artifactId>
</dependency>
<dependency>
- <groupId>net.sourceforge.pjl-comp-filter</groupId>
- <artifactId>pjl-comp-filter</artifactId>
+ <groupId>net.sourceforge.pjl-comp-filter</groupId>
+ <artifactId>pjl-comp-filter</artifactId>
</dependency>
-
+
<dependency>
+ <groupId>com.jolira</groupId>
+ <artifactId>guice</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.sisu.inject</groupId>
+ <artifactId>guice-servlet</artifactId>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+
+
+ <!-- transitive dependencies not picked up by jsword -->
+ <dependency>
+ <groupId>javatar</groupId>
+ <artifactId>javatar</artifactId>
+ <version>${javatar.version}</version>
+ </dependency>
+
</dependencies>
-
+
<build>
<finalName>step-web</finalName>
</build>
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/StepServletConfig.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/StepServletConfig.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/StepServletConfig.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,27 @@
+package com.tyndalehouse.step.guice;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.servlet.GuiceServletContextListener;
+import com.google.inject.servlet.ServletModule;
+import com.tyndalehouse.step.core.guice.StepCoreModule;
+import com.tyndalehouse.step.rest.controllers.FrontController;
+
+/**
+ * Configures the listener for the web app to return the injector used to configure the whole of the application
+ *
+ * @author Chris
+ *
+ */
+public class StepServletConfig extends GuiceServletContextListener {
+
+ @Override
+ protected Injector getInjector() {
+ return Guice.createInjector(new StepCoreModule(), new ServletModule() {
+ @Override
+ protected void configureServlets() {
+ serve("/rest/*").with(FrontController.class);
+ }
+ });
+ }
+}
Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/JsonExceptionResolver.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/JsonExceptionResolver.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/JsonExceptionResolver.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,24 +1,22 @@
package com.tyndalehouse.step.rest;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.web.servlet.HandlerExceptionResolver;
-import org.springframework.web.servlet.ModelAndView;
-
-public class JsonExceptionResolver implements HandlerExceptionResolver {
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response,
- final Object handler, final Exception exception) {
-
- this.logger.error(exception.getMessage(), exception);
-
- final ModelAndView mav = new ModelAndView();
- mav.setViewName("MappingJacksonJsonView");
- mav.addObject("error", exception.getMessage());
- return mav;
- }
+/**
+ * A JSon exception resolver
+ *
+ * @author Chris
+ *
+ */
+public class JsonExceptionResolver /* implements HandlerExceptionResolver */{
+ // private final Logger logger = LoggerFactory.getLogger(getClass());
+ //
+ // public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response,
+ // final Object handler, final Exception exception) {
+ //
+ // this.logger.error(exception.getMessage(), exception);
+ //
+ // final ModelAndView mav = new ModelAndView();
+ // mav.setViewName("MappingJacksonJsonView");
+ // mav.addObject("error", exception.getMessage());
+ // return mav;
+ // }
}
Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BibleController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BibleController.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BibleController.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -8,35 +8,45 @@
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.ResponseBody;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
import com.tyndalehouse.step.core.models.BibleVersion;
import com.tyndalehouse.step.core.models.EnrichedLookupOption;
import com.tyndalehouse.step.core.models.LookupOption;
import com.tyndalehouse.step.core.service.BibleInformationService;
import com.tyndalehouse.step.rest.wrappers.HtmlWrapper;
- at RequestMapping(value = "/bible", method = RequestMethod.GET)
- at Controller
+/**
+ * The controller for retrieving information on the bible or texts from the bible
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
public class BibleController {
- @Autowired
- private BibleInformationService bibleInformation;
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private static final long serialVersionUID = -5176839737814243641L;
+ private static final Logger LOGGER = LoggerFactory.getLogger(BibleController.class);
+ private final BibleInformationService bibleInformation;
/**
+ * creates the controller giving access to bible information
+ *
+ * @param bibleInformation the service allowing access to biblical material
+ */
+ @Inject
+ public BibleController(final BibleInformationService bibleInformation) {
+ this.bibleInformation = bibleInformation;
+ LOGGER.debug("Created Bible Controller");
+ }
+
+ /**
* a REST method that returns version of the Bible that are available
*
* @return all versions of modules that are considered to be Bibles.
*/
- @RequestMapping(value = "/versions")
- public @ResponseBody
- List<BibleVersion> getBibleVersions() {
- return this.bibleInformation.getBibleVersions();
+ public List<BibleVersion> getBibleVersions() {
+ return this.bibleInformation.getAvailableBibleVersions();
}
/**
@@ -46,9 +56,7 @@
* @param reference the reference to lookup
* @return the text to be displayed, formatted as HTML
*/
- @RequestMapping(value = "/text/{version}/{reference}")
- public @ResponseBody
- HtmlWrapper getBibleText(@PathVariable final String version, @PathVariable final String reference) {
+ public HtmlWrapper getBibleText(final String version, final String reference) {
return getBibleText(version, reference, null, null);
}
@@ -57,12 +65,10 @@
*
* @param version the initials identifying the version
* @param reference the reference to lookup
+ * @param options the list of options to be passed through and affect the retrieval process
* @return the text to be displayed, formatted as HTML
*/
- @RequestMapping(value = "/text/{version}/{reference}/{options}")
- public @ResponseBody
- HtmlWrapper getBibleText(@PathVariable final String version, @PathVariable final String reference,
- @PathVariable final String options) {
+ public HtmlWrapper getBibleText(final String version, final String reference, final String options) {
return getBibleText(version, reference, options, null);
}
@@ -72,12 +78,11 @@
* @param version the initials identifying the version
* @param reference the reference to lookup
* @param options a list of options to be passed in
+ * @param interlinearVersion the interlinear version if provided adds lines under the text
* @return the text to be displayed, formatted as HTML
*/
- @RequestMapping(value = "/text/{version}/{reference}/{options}/{interlinearVersion}")
- public @ResponseBody
- HtmlWrapper getBibleText(@PathVariable final String version, @PathVariable final String reference,
- @PathVariable final String options, @PathVariable final String interlinearVersion) {
+ public HtmlWrapper getBibleText(final String version, final String reference, final String options,
+ final String interlinearVersion) {
Validate.notEmpty(version, "You need to provide a version");
Validate.notEmpty(reference, "You need to provide a reference");
@@ -100,18 +105,19 @@
/**
* a REST method that returns version of the Bible that are available
*
+ * @param version the version initials or full version name to retrieve the versions for
* @return all versions of modules that are considered to be Bibles.
*/
- @RequestMapping(value = "/features/{version}")
- public @ResponseBody
- List<LookupOption> getBibleVersions(@PathVariable final String version) {
+ public List<LookupOption> getFeatures(final String version) {
return this.bibleInformation.getFeaturesForVersion(version);
}
- @RequestMapping(value = "/features-all")
- public @ResponseBody
- List<EnrichedLookupOption> getAllFeatures() {
- // Use EH Cache to cache this
+ /**
+ * retrieves the list of features currently supported by the application
+ *
+ * @return a list of features currently supported by the application
+ */
+ public List<EnrichedLookupOption> getAllFeatures() {
return this.bibleInformation.getAllFeatures();
}
}
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,293 @@
+package com.tyndalehouse.step.rest.controllers;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.core.exceptions.StepInternalException;
+
+/**
+ * The FrontController acts like a minimal REST server. The paths are resolved as follows:
+ *
+ * /step-web/rest/controllerName/methodName/arg1/arg2/arg3
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class FrontController extends HttpServlet {
+ private static final String UTF_8_ENCODING = "UTF-8";
+ private static final Logger LOGGER = LoggerFactory.getLogger(FrontController.class);
+ private static final char PACKAGE_SEPARATOR = '.';
+ private static final long serialVersionUID = 7898656504631346047L;
+ private static final String CONTROLLER_SUFFIX = "Controller";
+ private final Map<String, String> contextPath = new HashMap<String, String>();
+ private final transient Injector guiceInjector;
+ // TODO but also check threadsafety and whether we should share this object
+ private final transient ObjectMapper jsonMapper = new ObjectMapper();
+ private final Map<String, Method> methodNames = new HashMap<String, Method>();
+ private final Map<String, Object> controllers = new HashMap<String, Object>();
+
+ /**
+ * creates the front controller which will dispatch all the requests
+ *
+ * @param guiceInjector the injector used to call the relevant controllers
+ */
+ @Inject
+ public FrontController(final Injector guiceInjector) {
+ this.guiceInjector = guiceInjector;
+ }
+
+ @Override
+ protected void doGet(final HttpServletRequest req, final HttpServletResponse response) {
+ // fast string manipulation... (?)
+ final String requestURI = req.getRequestURI();
+ LOGGER.debug("Processing {}", requestURI);
+
+ final int requestStart = getPath(req).length() + 1;
+ final int endOfControllerName = requestURI.indexOf('/', requestStart);
+ final int startOfMethodName = endOfControllerName + 1;
+ final String controllerName = requestURI.substring(requestStart, endOfControllerName);
+ final String methodName = requestURI.substring(startOfMethodName,
+ requestURI.indexOf('/', startOfMethodName));
+ final int endOfMethodName = startOfMethodName + methodName.length();
+
+ LOGGER.debug("Request parsed as controller: [{}], method [{}]", controllerName, methodName);
+
+ // controller instance on which to call a method
+ final Object controllerInstance = getController(controllerName);
+
+ // some arguments to be passsed through
+ final Object[] args = getArgs(requestURI, endOfMethodName + 1);
+
+ // resolve method
+ final Method controllerMethod = getControllerMethod(methodName, controllerInstance, args);
+
+ try {
+ // invoke the three together
+ final Object returnVal = controllerMethod.invoke(controllerInstance, args);
+ final String jsonReturnValue = this.jsonMapper.writeValueAsString(returnVal);
+
+ final byte[] jsonEncoded = jsonReturnValue.getBytes(UTF_8_ENCODING);
+
+ // put results in cache if method is annotated. We don't need to do that
+ // afterwards...
+ setupHeaders(response, jsonEncoded.length);
+ response.getOutputStream().write(jsonEncoded);
+ // response.getOutputStream().flush();
+ // response.getOutputStream().close();
+
+ // perhaps we want to cache things...
+ // TODO
+
+ } catch (final StepInternalException e) {
+ // TODO handle this slightly differently?
+ doError(e);
+ } catch (final NoSuchMethodError e) {
+ doError(e);
+ } catch (final IllegalAccessException e) {
+ doError(e);
+ } catch (final InvocationTargetException e) {
+ doError(e);
+ } catch (final JsonGenerationException e) {
+ doError(e);
+ } catch (final JsonMappingException e) {
+ doError(e);
+ } catch (final IOException e) {
+ doError(e);
+ }
+ }
+
+ /**
+ * sets up the headers and the length of the message
+ *
+ * @param response the response
+ * @param length the length of the message
+ */
+ private void setupHeaders(final HttpServletResponse response, final int length) {
+ // we ensure that headers are set up appropriately
+ response.addDateHeader("Date", System.currentTimeMillis());
+ response.setCharacterEncoding(UTF_8_ENCODING);
+ response.setContentType("application/json");
+ response.setContentLength(length);
+ }
+
+ /**
+ * deals with an error whilst executing the request
+ *
+ * @param e the exception
+ */
+ private void doError(final Throwable e) {
+ LOGGER.error(e.getMessage(), e);
+
+ // TODO deal with error here:
+
+ }
+
+ /**
+ * Retrieves a controller, either from the cache, or from Guice
+ *
+ * @param controllerName the name of the controller (used as the key for the cache)
+ * @return the controller object
+ */
+ Object getController(final String controllerName) {
+ Object controllerInstance = this.controllers.get(controllerName);
+
+ // if retrieving yields null, get controller from Guice, and put in cache
+ if (controllerInstance == null) {
+ // make up the full class name
+ final String packageName = getClass().getPackage().getName();
+ final StringBuilder className = new StringBuilder(packageName.length() + controllerName.length()
+ + CONTROLLER_SUFFIX.length() + 1);
+
+ className.append(packageName);
+ className.append(PACKAGE_SEPARATOR);
+ className.append(Character.toUpperCase(controllerName.charAt(0)));
+ className.append(controllerName.substring(1));
+ className.append(CONTROLLER_SUFFIX);
+
+ try {
+ final Class<?> controllerClass = Class.forName(className.toString());
+ controllerInstance = this.guiceInjector.getInstance(controllerClass);
+
+ // we use the controller name as it came in to key the map
+ this.controllers.put(controllerName, controllerInstance);
+ } catch (final ClassNotFoundException e) {
+ throw new StepInternalException("Unable to find a controller for " + className, e);
+ }
+ }
+ return controllerInstance;
+ }
+
+ /**
+ * Returns the method to be invoked upon the controller
+ *
+ * @param methodName the method name
+ * @param controllerInstance the instance of the controller
+ * @param args the list of arguments, required to resolve the correct method if they have arguments
+ * @return the method to be invoked
+ */
+ Method getControllerMethod(final String methodName, final Object controllerInstance, final Object[] args) {
+ final Class<? extends Object> controllerClass = controllerInstance.getClass();
+
+ // try cache first
+ final String cacheKey = getCacheKey(controllerClass.getName(), methodName, args.length);
+
+ // retrieve method from cache, or put in cache if not there
+ Method controllerMethod = this.methodNames.get(cacheKey);
+ if (controllerMethod == null) {
+ // resolve method
+ try {
+ controllerMethod = controllerClass.getMethod(methodName, getClasses(args));
+
+ // put method in cache
+ this.methodNames.put(cacheKey, controllerMethod);
+ } catch (final NoSuchMethodException e) {
+ throw new StepInternalException(e.getMessage(), e);
+ }
+ }
+ return controllerMethod;
+ }
+
+ /**
+ * @param args a number of arguments
+ * @return an array of classes matching the list of arguments passed in
+ */
+ Class<?>[] getClasses(final Object[] args) {
+ if (args == null) {
+ return new Class<?>[0];
+ }
+
+ final Class<?>[] classes = new Class<?>[args.length];
+
+ for (int ii = 0; ii < classes.length; ii++) {
+ classes[ii] = args[ii].getClass();
+ }
+
+ return classes;
+ }
+
+ /**
+ * returns the cache key to resolve from the cache
+ *
+ * @param controllerName the controller name
+ * @param methodName the method name
+ * @param numArgs the number of arguments affects which method is returned
+ * @return the key to the method as expected in the cache.
+ */
+ String getCacheKey(final String controllerName, final String methodName, final int numArgs) {
+ final StringBuilder cacheKeyBuffer = new StringBuilder(controllerName.length() + methodName.length());
+ cacheKeyBuffer.append(controllerName);
+ cacheKeyBuffer.append(methodName);
+ cacheKeyBuffer.append(numArgs);
+ return cacheKeyBuffer.toString();
+ }
+
+ /**
+ * gets the arguments out of the requestURI String
+ *
+ * @param requestURI the request URI string
+ * @param parameterStart the location at which the parameters start
+ * @return a list of arguments
+ */
+ String[] getArgs(final String requestURI, final int parameterStart) {
+ final List<String> arguments = new ArrayList<String>();
+ int argStart = parameterStart;
+ int nextArgStop = requestURI.indexOf('/', argStart);
+ try {
+ while (nextArgStop != -1) {
+ arguments.add(URLDecoder.decode(requestURI.substring(argStart, nextArgStop), UTF_8_ENCODING));
+ argStart = nextArgStop + 1;
+ nextArgStop = requestURI.indexOf('/', argStart);
+ }
+ } catch (final UnsupportedEncodingException e) {
+ throw new StepInternalException(e.getMessage(), e);
+ }
+
+ // add the last argument
+ if (argStart < requestURI.length()) {
+ try {
+ arguments.add(URLDecoder.decode(requestURI.substring(argStart), UTF_8_ENCODING));
+ } catch (final UnsupportedEncodingException e) {
+ throw new StepInternalException("Unable to decode last argument", e);
+ }
+ }
+ return arguments.toArray(new String[arguments.size()]);
+ }
+
+ /**
+ * Retrieves the path from the request
+ *
+ * @param req the request
+ * @return the concatenated request
+ */
+ String getPath(final HttpServletRequest req) {
+ final String servletPath = req.getServletPath();
+ String path = this.contextPath.get(servletPath);
+
+ if (path == null) {
+ path = super.getServletContext().getContextPath() + servletPath;
+ this.contextPath.put(servletPath, path);
+ }
+ return path;
+ }
+}
Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/ModuleController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/ModuleController.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/ModuleController.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,33 +1,57 @@
package com.tyndalehouse.step.rest.controllers;
+import java.util.List;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.ResponseBody;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.core.models.BibleVersion;
import com.tyndalehouse.step.core.service.ModuleService;
- at RequestMapping(value = "/module", method = RequestMethod.GET)
- at Controller
+/**
+ * The Module Controller servicing requests for module information
+ */
public class ModuleController {
- @Autowired
- private ModuleService moduleDefintions;
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private static final Logger LOGGER = LoggerFactory.getLogger(ModuleController.class);
+ private final ModuleService moduleDefintions;
/**
+ * sets up the controller to access module information
+ *
+ * @param moduleDefintions the service allowing access to module information
+ */
+ @Inject
+ public ModuleController(final ModuleService moduleDefintions) {
+ this.moduleDefintions = moduleDefintions;
+ }
+
+ /**
* a REST method that returns version of the Bible that are available
*
- * @param reference a reference for a module to lookup
* @return all versions of modules that are considered to be Bibles.
*/
- @RequestMapping(value = "/definitions/{reference}")
- public @ResponseBody
- String getDefinition(@PathVariable final String reference) {
- this.logger.debug("Getting definition for {}", reference);
+ public List<BibleVersion> getAllModules() {
+ return this.moduleDefintions.getAvailableModules();
+ }
+
+ /**
+ * a REST method that returns version of the Bible that are not yet installed
+ *
+ * @return all versions of modules that are considered to be modules and usable by STEP.
+ */
+ public List<BibleVersion> getAllInstallableModules() {
+ return this.moduleDefintions.getAllInstallableModules();
+ }
+
+ /**
+ * a REST method that returns all the definitions for a particular key
+ *
+ * @param reference a reference for a module to lookup
+ * @return the definition(s) that can be resolved from the reference provided
+ */
+ public String getDefinition(final String reference) {
+ LOGGER.debug("Getting definition for {}", reference);
return this.moduleDefintions.getDefinition(reference).getExplanation();
}
}
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/SetupController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/SetupController.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/SetupController.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,63 @@
+package com.tyndalehouse.step.rest.controllers;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.core.service.BibleInformationService;
+
+/**
+ * The controller that will deal with any requests changing the behaviour of the application
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class SetupController {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SetupController.class);
+ private final BibleInformationService bibleInformation;
+
+ /**
+ * creates the controller
+ *
+ * @param bibleInformationService the service that allows access to biblical material
+ */
+ @Inject
+ public SetupController(final BibleInformationService bibleInformationService) {
+ this.bibleInformation = bibleInformationService;
+ }
+
+ /**
+ * a REST method to retrieve events between two dates The arrays match in index, and go by three (timebandId, from,
+ * to), (timebandId, from, to), ...
+ *
+ * @return true if the software reckons this is the first time
+ */
+ // @RequestMapping("/isFirstTime")
+ public boolean isFirstTime() {
+ LOGGER.debug("Checking whether this is the first time the software is being run");
+ return !this.bibleInformation.hasCoreModules();
+ }
+
+ /**
+ * Installing default modules
+ *
+ */
+ // @RequestMapping("/install/defaultModules")
+ public void installDefaultModules() {
+ LOGGER.debug("Installing default modules");
+ this.bibleInformation.installDefaultModules();
+ }
+
+ /**
+ * Installing default modules
+ *
+ * @param reference the initials of the bible to install
+ */
+ // @RequestMapping("/install/book/{reference}")
+ public void installBible(final String reference) {
+ LOGGER.debug("Installing module {}", reference);
+ this.bibleInformation.installModules(reference);
+ }
+}
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/TimelineController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/TimelineController.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/TimelineController.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,48 @@
+package com.tyndalehouse.step.rest.controllers;
+
+import java.util.Date;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Singleton;
+
+/**
+ * The timeline controller retrieves information about past events
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class TimelineController {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TimelineController.class);
+
+ /**
+ * a REST method to retrieve events between two dates The arrays match in index, and go by three (timebandId, from,
+ * to), (timebandId, from, to), ...
+ *
+ * @param timebandId the timeband ids
+ * @param from the from dates
+ * @param to the to dates
+ * @return all versions of modules that are considered to be Bibles. TODO work out UK date format mappings
+ */
+ // @RequestMapping("/events")
+ public String getEvents(final String[] timebandId, final Date from, final Date to) {
+ LOGGER.debug("Retrieving events between [{}] and [{}]", from, to);
+ return timebandId[0];
+ }
+
+ /**
+ * Retrieves events based on a biblical reference. This method also needs to return an origin and a scale for the
+ * timeline to be displayed properly as it might well be that the UI has carried out a different search
+ *
+ * @param bibleReference the bible reference that might have a set of events related to it
+ * @return a list of events to be shown on a timeline, including the origin of the timeline and the scale of the
+ * timeline
+ */
+ // @RequestMapping("/eventsFromReference")
+ public String getEventsFromReference(final String bibleReference) {
+
+ return null;
+ }
+}
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/Cached.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/Cached.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/Cached.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,22 @@
+package com.tyndalehouse.step.rest.framework;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * This indicates that the REST-like call can be cached by the server
+ *
+ * @author Chris
+ *
+ */
+ at Target(METHOD)
+ at Retention(RUNTIME)
+public @interface Cached {
+ /** true to indicate that the results from the method can be cached */
+ // CHECKSTYLE:OFF
+ boolean value = false;
+ // CHECKSTYLE:ON
+}
Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/wrappers/HtmlWrapper.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/wrappers/HtmlWrapper.java 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/wrappers/HtmlWrapper.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -1,12 +1,26 @@
package com.tyndalehouse.step.rest.wrappers;
+/**
+ * A simple wrapper around a string for returning as a JSON-mapped object
+ *
+ * @author Chris
+ *
+ */
public class HtmlWrapper {
- final String value;
+ private final String value;
+ /**
+ * the value to be wrapped
+ *
+ * @param value the value to be wrapped around
+ */
public HtmlWrapper(final String value) {
this.value = value;
}
+ /**
+ * @return the value to be returned
+ */
public String getValue() {
return this.value;
}
Modified: trunk/step/step-web/src/main/webapp/WEB-INF/web.xml
===================================================================
--- trunk/step/step-web/src/main/webapp/WEB-INF/web.xml 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/webapp/WEB-INF/web.xml 2010-12-19 11:27:36 UTC (rev 195)
@@ -5,56 +5,30 @@
<web-app>
<display-name>STEP :: Scripture Tools for Every Pastor</display-name>
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:com/tyndalehouse/step/**/config/*-applicationContext.xml</param-value>
- </context-param>
-
<filter>
- <filter-name>requestEncodingFilter</filter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
- <init-param>
- <param-name>encoding</param-name>
- <param-value>UTF-8</param-value>
- </init-param>
- <init-param>
- <param-name>forceEncoding</param-name>
- <param-value>true</param-value>
- </init-param>
+ <filter-name>guiceFilter</filter-name>
+ <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
+
<filter>
<filter-name>CompressingFilter</filter-name>
<filter-class>com.planetj.servlet.filter.compression.CompressingFilter</filter-class>
</filter>
- <!-- don't need to do all the time TODO -->
<filter-mapping>
- <filter-name>requestEncodingFilter</filter-name>
+ <filter-name>CompressingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
+
<filter-mapping>
- <filter-name>CompressingFilter</filter-name>
+ <filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
+
<listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ <listener-class>com.tyndalehouse.step.guice.StepServletConfig</listener-class>
</listener>
-
- <!-- Spring context Configuration Begins -->
-
- <servlet>
- <servlet-name>step-rest</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>step-rest</servlet-name>
- <url-pattern>/rest/*</url-pattern>
- </servlet-mapping>
-
-
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Added: trunk/step/step-web/src/main/webapp/css/setup-layout.css
===================================================================
--- trunk/step/step-web/src/main/webapp/css/setup-layout.css (rev 0)
+++ trunk/step/step-web/src/main/webapp/css/setup-layout.css 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,22 @@
+#installationOptions {
+ min-height: 300px;
+ height: 100%;
+}
+
+#leftColumn {
+ width: 49%;
+ float: left;
+}
+
+#rightColumn {
+ width: 49%;
+ float: left;
+}
+
+.installed {
+ color: green;
+}
+
+.notInstalled {
+ color: red;
+}
Modified: trunk/step/step-web/src/main/webapp/index.jsp
===================================================================
--- trunk/step/step-web/src/main/webapp/index.jsp 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/webapp/index.jsp 2010-12-19 11:27:36 UTC (rev 195)
@@ -18,7 +18,7 @@
<script src="js/util.js" type="text/javascript"></script>
<script src="js/passage_toolbar.js" type="text/javascript"></script>
<script src="js/passage.js" type="text/javascript"></script>
-<!-- <script src="js/bookmark.js" type="text/javascript"></script>-->
+ <script src="js/bookmark.js" type="text/javascript"></script>
<script src="js/lexicon_definition.js" type="text/javascript"></script>
<script src="js/ui_hooks.js" type="text/javascript"></script>
<script src="js/init.js" type="text/javascript"></script>
@@ -44,7 +44,7 @@
<div class="ui-layout-north northBookmark">
<img src="images/step-logo.png" alt="STEP :: Scripture Tools for Every Pastor" />
</div>
- <div class="ui-layout-center bookmarksContent">b</div>
+ <div id="bookmarkPane" class="ui-layout-center bookmarksContent"><span>Bookmarks</span></div>
<div class="ui-layout-south logo">
<span class="copyright">© Tyndale House</span>
</div>
Modified: trunk/step/step-web/src/main/webapp/js/bookmark.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/bookmark.js 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/webapp/js/bookmark.js 2010-12-19 11:27:36 UTC (rev 195)
@@ -5,18 +5,28 @@
*/
function Bookmark(bookmarkContainer) {
this.bookmarkContainer = bookmarkContainer;
+ var self = this;
- //for bookmarks, we will only have a few, therefore we store them in an array for now:
- //we will store the elements in here, with their jquery wrapper
- this.currentBookmarks = [];
+ //listen to passage changes
+ this.bookmarkContainer.hear("passage-change", function(selfElement, data) {
+ self.addHistory(data);
+ });
}
-//
-///**
-// * Adding a bookmark
-// */
-//Bookmark.prototype.add = function(passageReference) {
-// var bookmark = this.get(passageReference);
+
+/**
+ * Adding a bookmark
+ */
+Bookmark.prototype.addHistory = function(passageReference) {
+ //construct bookmark
+// var item = "<span>" + passageReference + "</span>";
+// $("#bookmarkPane span").prepend(item);
+}
+
+
+
+
+ // var bookmark = this.get(passageReference);
// if(bookmark) {
// //move bookmark around
//
Modified: trunk/step/step-web/src/main/webapp/js/init.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/init.js 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/webapp/js/init.js 2010-12-19 11:27:36 UTC (rev 195)
@@ -12,6 +12,7 @@
initGlobalHandlers();
initDefaultValues();
initLexicon();
+ initBookmarks();
initData();
});
}
@@ -100,7 +101,7 @@
function initData() {
//get all supported versions
var options;
- $.getJSON("rest/bible/features-all", function(data) {
+ $.getJSON(BIBLE_GET_ALL_FEATURES, function(data) {
$.each(data, function() {
options = data;
});
@@ -113,7 +114,7 @@
//we reserve the first spot for "ALL Versions"
var ii = 1;
- $.getJSON("rest/bible/versions", function(data) {
+ $.getJSON(BIBLE_GET_BIBLE_VERSIONS, function(data) {
var parsedResponse = $.map(data, function(item) {
var showingText = "[" + item.initials + "] " + item.name;
@@ -222,9 +223,14 @@
}
function initLexicon() {
- var lexicon = new LexiconDefinition();
+ new LexiconDefinition();
}
+function initBookmarks() {
+ new Bookmark($("#bookmarkPane"));
+}
+
+
function raiseError(error) {
$("#error").text(error);
$('body').layout().open("north");
Modified: trunk/step/step-web/src/main/webapp/js/lexicon_definition.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/lexicon_definition.js 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/webapp/js/lexicon_definition.js 2010-12-19 11:27:36 UTC (rev 195)
@@ -41,7 +41,7 @@
var tabs = s.split(" ");
$(tabs).each(function() {
- popup.tabs("add", "rest/module/definitions/" + this, self.getShortKey(this));
+ popup.tabs("add", MODULE_GET_DEFINITION + this, self.getShortKey(this));
});
popup.tabs("option", {
Modified: trunk/step/step-web/src/main/webapp/js/passage.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/passage.js 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/webapp/js/passage.js 2010-12-19 11:27:36 UTC (rev 195)
@@ -31,7 +31,6 @@
text: false
}).change(function() {
this.checked ? self.columnLayout.open("north") : self.columnLayout.close("north");
-// this.checked ? self.toolbar.open() : self.toolbar.close();
});
@@ -98,7 +97,7 @@
var self = this;
if(this.version.val() && this.reference.val() && this.version.val() != "" && this.reference.val() != "") {
- var url = "rest/bible/text/" + this.version.val() + "/" + this.reference.val();
+ var url = BIBLE_GET_BIBLE_TEXT + this.version.val() + "/" + this.reference.val();
if(options && options.length != 0) {
url += "/" + options ;
@@ -112,6 +111,9 @@
$.get(url, function (text) {
//we get html back, so we insert into passage:
self.passage.html(text.value);
+
+ //passage change was successful, so we let the rest of the UI know
+ $.shout("passage-change", self.reference.val());
});
}
}
Modified: trunk/step/step-web/src/main/webapp/js/passage_toolbar.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/passage_toolbar.js 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/webapp/js/passage_toolbar.js 2010-12-19 11:27:36 UTC (rev 195)
@@ -119,7 +119,7 @@
var self = this;
//query the server for features
- $.getJSON("rest/bible/features/" + version, function (features) {
+ $.getJSON(BIBLE_GET_FEATURES + version, function (features) {
//for each button, if in array, then enable, otherwise disable
//TODO: for some reason there are sometime some initialisation issues which throw an exception
Added: trunk/step/step-web/src/main/webapp/js/setup.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/setup.js (rev 0)
+++ trunk/step/step-web/src/main/webapp/js/setup.js 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,39 @@
+$(document).ready(function() {
+ setup();
+});
+
+/**
+ * This method sets up the main page allowing the user to install modules as he/she wishes
+ */
+function setup() {
+ $("#installCoreModules").click(function() {
+ // we add a click handler that installs the default modules
+ $.getJSON(SETUP_INSTALL_DEFAULT_MODULES, function(data) {
+ // installation has started - so now we can afford to make calls to the internet:
+ // set up available modules - to do extend to everything...
+ $.getJSON(MODULE_GET_ALL_INSTALLABLE_MODULES, function(data) {
+ $(data).each(function() {
+ var toBeInstalled = "<a class='notInstalled' href=\"javascript:installVersion('" + this.initials + "','" +
+ this.name.replace(/'/g,"\\'") + "')\">[" + this.initials + "] " + this.name + " - Installed</a><br />";
+ $("#availableModules").append(toBeInstalled);
+ })
+ });
+ });
+ });
+
+ // set up available modules - to do extend to everything...
+ $.getJSON(MODULE_GET_ALL_MODULES, function(data) {
+ $(data).each(function() {
+ var installed = "<div class=\"installed\">[" + this.initials + "] " + this.name + " - Installed</div>";
+ $("#inProgressModules").append(installed);
+ })
+ });
+}
+
+function installVersion(initials, name) {
+ $.getJSON(SETUP_INSTALL_BIBLE + initials, function(data) {
+ //set up a progress bar on the other side...
+ });
+}
+
+
Modified: trunk/step/step-web/src/main/webapp/js/ui_hooks.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/ui_hooks.js 2010-12-03 19:26:36 UTC (rev 194)
+++ trunk/step/step-web/src/main/webapp/js/ui_hooks.js 2010-12-19 11:27:36 UTC (rev 195)
@@ -3,6 +3,29 @@
* The aim is to redirect the calls quickly to other parts of the UI
*/
+/////////////////////////////////////////////////////////////////////////
+// The following section defines method names and controller names
+// These are used as part of the rest-like calls
+/////////////////////////////////////////////////////////////////////////
+BIBLE_GET_BIBLE_VERSIONS = "rest/bible/getBibleVersions/";
+BIBLE_GET_BIBLE_TEXT = "rest/bible/getBibleText/";
+BIBLE_GET_FEATURES = "rest/bible/getFeatures/";
+BIBLE_GET_ALL_FEATURES = "rest/bible/getAllFeatures/";
+
+MODULE_GET_ALL_MODULES = "rest/module/getAllModules/";
+MODULE_GET_ALL_INSTALLABLE_MODULES = "rest/module/getAllModules/";
+MODULE_GET_DEFINITION = "rest/module/getDefinition/";
+
+SETUP_IS_FIRST_TIME = "rest/setup/isFirstTime/";
+SETUP_INSTALL_DEFAULT_MODULES = "rest/setup/installDefaultModules/";
+SETUP_INSTALL_BIBLE = "rest/setup/installBible/";
+
+TIMELINE_GET_EVENTS = "rest/timeline/getEvents/";
+TIMELINE_GET_EVENTS_FROM_REFERENCE = "rest/timeline/getEventsFromReference/";
+
+
+
+
/**
* called when click on a piece of text.
* @param strongMorphs all the strongs and morphs associated with this "word"
Added: trunk/step/step-web/src/main/webapp/setup.jsp
===================================================================
--- trunk/step/step-web/src/main/webapp/setup.jsp (rev 0)
+++ trunk/step/step-web/src/main/webapp/setup.jsp 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML>
+<HEAD>
+
+ <META http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <TITLE>STEP :: Scripture Tools for Every Pastor</TITLE>
+
+ <link rel="stylesheet" type="text/css" href="css/ui-layout/layout-default.css" />
+ <link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.8.5.custom.css" />
+ <link rel="stylesheet" type="text/css" href="css/initial-layout.css" />
+ <link rel="stylesheet" type="text/css" href="css/initial-fonts.css" />
+ <link rel="stylesheet" type="text/css" href="css/setup-layout.css" />
+
+ <script src="libs/jquery-1.4.2.min.js" type="text/javascript"></script>
+ <script src="libs/jquery-ui-1.8.5.custom.min.js" type="text/javascript"></script>
+ <script src="libs/jquery.layout-latest.js" type="text/javascript"></script>
+ <script src="libs/jquery-shout.js" type="text/javascript"></script>
+
+ <script src="js/setup.js" type="text/javascript"></script>
+</HEAD>
+<body>
+
+ <h1>STEP - Scripture Tools for Every Pastor</h1>
+
+ This is setup page for the STEP software.
+ This page enables you to install different modules used by STEP, including Bibles, Dictionaries, ...
+ <p />
+
+ <!-- If the user lives in a country that persecutes Christians then actions on this page might give the game away -->
+ <b>Please note that actions on this page access the internet. If you are in a "sensitive" country, you may wish to wait before you install any modules.</b>
+ <p />
+
+ A number of modules must be installed for core functionality to be available.
+ <input id="installCoreModules" type="button" value="Install core functionality" />
+
+ <div id="installationOptions">
+ <div id="leftColumn" class="column ui-layout-center">
+ <h2>Available modules</h2>
+
+ <input id="filter" type="text" value="Filter" />
+
+ <!-- list of links of all available modules, including
+ dictionaries, broken down by categories -->
+ <div id="availableModules"></div>
+ </div>
+
+ <div id="rightColumn" class="column ui-layout-east">
+ <h2>Installed modules</h2>
+ <div id="inProgressModules"></div>
+ </div>
+ </div>
+</body>
+</HTML>
Added: trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java
===================================================================
--- trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java (rev 0)
+++ trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java 2010-12-19 11:27:36 UTC (rev 195)
@@ -0,0 +1,126 @@
+package com.tyndalehouse.step.rest.controllers;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+import org.junit.Test;
+
+import com.google.inject.Injector;
+import com.tyndalehouse.step.core.service.BibleInformationService;
+
+/**
+ * tests the front controller parsing process
+ *
+ * @author Chris
+ *
+ */
+public class FrontControllerTest {
+
+ /**
+ * tests that arguments are parsed correctly given the correct start
+ */
+ @Test
+ public void testGetArgs() {
+ // index starts at ...........0123456789-123456789-123456
+ final String sampleRequest = "step-web/rest/bible/get/1K2/2K2";
+
+ final FrontController fc = new FrontController(mock(Injector.class));
+
+ // when
+ final Object[] args = fc.getArgs(sampleRequest, 24);
+
+ // then
+ assertEquals(2, args.length);
+ assertEquals("1K2", args[0]);
+ assertEquals("2K2", args[1]);
+ }
+
+ /**
+ * tests that parsing of request works if request finishes with a slash
+ */
+ @Test
+ public void testGetArgsFinishingWithSlash() {
+ // index starts at ...........0123456789-123456789-123456
+ final String sampleRequest = "step-web/rest/bible/get/1K2/2K2/";
+
+ final FrontController fc = new FrontController(mock(Injector.class));
+
+ // when
+ final Object[] args = fc.getArgs(sampleRequest, 24);
+
+ // then
+ assertEquals(2, args.length);
+ assertEquals("1K2", args[0]);
+ assertEquals("2K2", args[1]);
+ }
+
+ /**
+ * tests generation of cache key
+ */
+ @Test
+ public void testCacheKey() {
+ assertEquals("controllergetName",
+ new FrontController(mock(Injector.class)).getCacheKey("controller", "getName", null));
+ }
+
+ /**
+ * tests that resolving method works
+ *
+ * @throws IllegalAccessException uncaught exception
+ * @throws InvocationTargetException uncaught exception
+ */
+ @Test
+ public void testGetControllerMethod() throws IllegalAccessException, InvocationTargetException {
+ final FrontController frontController = new FrontController(mock(Injector.class));
+ final BibleInformationService bibleInfo = mock(BibleInformationService.class);
+ final BibleController controllerInstance = new BibleController(bibleInfo);
+
+ // when
+ final Method controllerMethod = frontController.getControllerMethod("getBibleVersions",
+ controllerInstance, null);
+
+ // then
+ controllerMethod.invoke(controllerInstance);
+ verify(bibleInfo).getAvailableBibleVersions();
+ }
+
+ /**
+ * tests the get controller method
+ */
+ @Test
+ public void testGetController() {
+ final String controllerName = "Bible";
+ final Injector mockInjector = mock(Injector.class);
+ final FrontController frontController = new FrontController(mockInjector);
+
+ final BibleController mockController = mock(BibleController.class);
+ when(mockInjector.getInstance(BibleController.class)).thenReturn(mockController);
+
+ // when
+ final Object controller = frontController.getController(controllerName);
+
+ // then
+ assertEquals(controller.getClass(), mockController.getClass());
+ }
+
+ /**
+ * tests various combinations for getClasses
+ */
+ @Test
+ public void testGetClasses() {
+ final FrontController fc = new FrontController(null);
+
+ assertEquals(0, fc.getClasses(null).length);
+ assertEquals(0, fc.getClasses(new Object[0]).length);
+ assertArrayEquals(new Class<?>[] { String.class, ArrayList.class },
+ fc.getClasses(new Object[] { "hello", new ArrayList<String>() }));
+
+ }
+}
More information about the Tynstep-svn
mailing list