changeset 21:4ea0f81a5d08

little corrections
author Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
date Wed, 14 Dec 2011 12:49:06 +0100
parents 7d6d969b10cf
children 6a45a982c333
files software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/WEB-INF/classes/constants.properties software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/WEB-INF/lib/mpiwg-mpdl-lt-web.jar software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/WEB-INF/lib/mpiwg-mpdl-lt.jar software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/css/getDictionaryEntries.css software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/images/treecheckbox.png software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/index.html software/mpdl-services/mpiwg-mpdl-lt-web/dist-remote/mpiwg-mpdl-lt-web.jar software/mpdl-services/mpiwg-mpdl-lt-web/dist-remote/mpiwg-mpdl-lt-web.war software/mpdl-services/mpiwg-mpdl-lt-web/dist/mpiwg-mpdl-lt-web.jar software/mpdl-services/mpiwg-mpdl-lt-web/dist/mpiwg-mpdl-lt-web.war software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetDictionaryEntries.java software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetForms.java software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetLemmas.java software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/Tokenize.java software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/Transcode.java
diffstat 15 files changed, 391 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/WEB-INF/classes/constants.properties	Wed Dec 14 12:48:43 2011 +0100
+++ b/software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/WEB-INF/classes/constants.properties	Wed Dec 14 12:49:06 2011 +0100
@@ -1,1 +1,1 @@
-dataDir=/usr/local/tomcat-mpdl/mpdl-data/lt
\ No newline at end of file
+dataDir=/Users/jwillenborg/mpdl/data/lt
\ No newline at end of file
Binary file software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/WEB-INF/lib/mpiwg-mpdl-lt-web.jar has changed
Binary file software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/WEB-INF/lib/mpiwg-mpdl-lt.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/css/getDictionaryEntries.css	Wed Dec 14 12:49:06 2011 +0100
@@ -0,0 +1,95 @@
+.body {
+    margin:3px;
+    color: #000000;
+    background-color: #ebebeb;
+    min-width:1100px;
+}
+div.title {
+	font-size: 30px;
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+input.query {
+	border-radius: 5px;
+}
+span.inputType {
+  font-size: 22px;
+  font-weight:bold;
+  display:block;
+  margin-top: 10px;
+}
+
+.tree ul,
+.tree li {
+  padding: 0;
+  margin: 0;
+  margin-left: 10px;
+  list-style: none;
+}
+.tree input {
+  position: absolute;
+  opacity: 0;
+}
+.tree input + label + ul {
+  margin: 0 0 0 22px;
+}
+.tree input + label + ul {
+  display: none;
+}
+.tree label,
+.tree label::before {
+  cursor: pointer;
+}
+.tree input:disabled + label {
+  cursor: default;
+  opacity: .6;
+}
+.tree input:checked:not(:disabled) + label + ul {
+  display: block;
+}
+.tree label,
+.tree label::before {
+  background: url("/mpiwg-mpdl-lt-web/images/treecheckbox.png") no-repeat;
+}
+.tree label,
+.tree a,
+.tree label::before {
+  display: inline-block;
+  height: 16px;
+  line-height: 16px;,
+  vertical-align: middle;
+}
+.tree label {
+  background-position: 18px 0;
+}
+.tree label::before {
+  content: "";
+  width: 16px;
+  margin: 0 22px 0 0;
+  vertical-align: middle;
+  background-position: 0 -32px;
+}
+.tree input:checked + label::before {
+  background-position: 0 -16px;
+}
+
+/* webkit adjacent element selector bugfix */
+@media screen and (-webkit-min-device-pixel-ratio:0)
+{
+  .tree 
+  {
+    -webkit-animation: webkit-adjacent-element-selector-bugfix infinite 1s;
+  }
+  
+  @-webkit-keyframes webkit-adjacent-element-selector-bugfix 
+  {
+    from 
+    { 
+      padding: 0;
+    } 
+    to 
+    { 
+      padding: 0;
+    }
+  }
+}
Binary file software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/images/treecheckbox.png has changed
--- a/software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/index.html	Wed Dec 14 12:48:43 2011 +0100
+++ b/software/mpdl-services/mpiwg-mpdl-lt-web/WebContent/index.html	Wed Dec 14 12:49:06 2011 +0100
@@ -28,6 +28,12 @@
                 <li>by a prefix range: entries starting with a prefix (e.g. "a*")</li>
              </ul>
           </li>
+          <li>queryDisplay (optional)
+            <ul>
+              <li>display of the query</li>
+              <li>default: content of parameter "query"</li>
+            </ul>
+          </li>
           <li>inputType (optional)
             <ul>
               <li>"form"</li>
@@ -49,9 +55,19 @@
           </li>
           <li>outputType (optional)
             <ul>
-              <li>"compact"</li>
-              <li>"full"</li>
-              <li>default: "compact"</li>
+              <li>this parameter can occur many times (e.g. "outputType=morphCompact&amp;outputType=dictCompact")
+                <ul>
+                  <li>"morphCompact"</li>
+                  <li>"dictCompact"</li>
+                  <li>"wikiCompact"</li>
+                  <li>"allCompact" (all output types compact)</li>
+                  <li>"morphFull"</li>
+                  <li>"dictFull"</li>
+                  <li>"wikiFull"</li>
+                  <li>"allFull" (all output types full)</li>
+                </ul>
+              </li>
+              <li>default: "allCompact"</li>
             </ul>
           </li>
           <li>outputFormat (optional)
@@ -68,22 +84,29 @@
               <li>default: "norm"</li>
             </ul>
           </li>
-          <li>resultPage (optional)
+          <li>resultPageNumber (optional)
             <ul>
               <li>works only for range queries</li>
               <li>page number of the result (e.g. "2": result entries from position 51 to 100)</li>
               <li>default: "1"</li>
             </ul>
           </li>
+          <li>resultPageSize (optional)
+            <ul>
+              <li>works only for range queries</li>
+              <li>page size of the result (e.g. "100": each result page has a size of 100)</li>
+              <li>default: "50"</li>
+            </ul>
+          </li>
         </ul>
       </li>
       <li>Response output
         <ul>
           <li>dependent of outputFormat, outputType and resultPage: morphology, dictionary and Wikipedia entries in Xml or Html format</li>
+          <li>Example: <a href="lt/GetDictionaryEntries?query=a*&language=lat&outputFormat=html">query=a*&amp;language=lat&amp;outputFormat=html</a></li>
           <li>Example: <a href="lt/GetDictionaryEntries?query=a*&dictionary=ls">query=a*&amp;dictionary=ls</a></li>
-          <li>Example: <a href="lt/GetDictionaryEntries?query=a*&language=lat&outputFormat=html">query=a*&amp;language=lat&amp;outputFormat=html</a></li>
           <li>Example: <a href="lt/GetDictionaryEntries?query=revolution&language=eng">query=revolution&amp;language=lat</a></li>
-          <li>Example: <a href="lt/GetDictionaryEntries?query=multa&language=lat&outputFormat=html&outputType=full">query=multa&amp;language=lat&amp;outputFormat=html&amp;outputType=full</a></li>
+          <li>Example: <a href="lt/GetDictionaryEntries?query=multa&language=lat&outputFormat=html&outputType=allCompact">query=multa&amp;language=lat&amp;outputFormat=html&amp;outputType=allCompact</a></li>
         </ul>
       </li>
     </ul>
@@ -236,6 +259,13 @@
               <li>default: "norm"</li>
             </ul>
           </li>
+          <li>normalizationType (optional)
+            <ul>
+              <li>"dictionary"</li>
+              <li>"display"</li>
+              <li>default: "dictionary"</li>
+            </ul>
+          </li>
           <li>dictionary (optional)
             <ul>
               <li>"yes"</li>
Binary file software/mpdl-services/mpiwg-mpdl-lt-web/dist-remote/mpiwg-mpdl-lt-web.jar has changed
Binary file software/mpdl-services/mpiwg-mpdl-lt-web/dist-remote/mpiwg-mpdl-lt-web.war has changed
Binary file software/mpdl-services/mpiwg-mpdl-lt-web/dist/mpiwg-mpdl-lt-web.jar has changed
Binary file software/mpdl-services/mpiwg-mpdl-lt-web/dist/mpiwg-mpdl-lt-web.war has changed
--- a/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetDictionaryEntries.java	Wed Dec 14 12:48:43 2011 +0100
+++ b/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetDictionaryEntries.java	Wed Dec 14 12:49:06 2011 +0100
@@ -3,6 +3,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
 
@@ -15,12 +16,14 @@
 import org.apache.commons.lang3.StringEscapeUtils;
 
 import de.mpg.mpiwg.berlin.mpdl.exception.ApplicationException;
+import de.mpg.mpiwg.berlin.mpdl.lt.dict.app.Lexica;
 import de.mpg.mpiwg.berlin.mpdl.lt.dict.app.Lexicon;
 import de.mpg.mpiwg.berlin.mpdl.lt.dict.app.LexiconEntry;
 import de.mpg.mpiwg.berlin.mpdl.lt.dict.db.LexHandler;
 import de.mpg.mpiwg.berlin.mpdl.lt.general.Language;
 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Form;
 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Lemma;
+import de.mpg.mpiwg.berlin.mpdl.lt.text.norm.Normalizer;
 import de.mpg.mpiwg.berlin.mpdl.servlets.util.ServletUtil;
 
 public class GetDictionaryEntries extends HttpServlet {
@@ -45,47 +48,75 @@
     request.setCharacterEncoding("utf-8");
     response.setCharacterEncoding("utf-8");
     String query = request.getParameter("query");
+    String queryDisplay = request.getParameter("queryDisplay");
     String language = request.getParameter("language");
     String inputType = request.getParameter("inputType");
     String outputFormat = request.getParameter("outputFormat");
-    String outputType = request.getParameter("outputType");
+    String[] outputTypesArray = request.getParameterValues("outputType");
     String dictionary = request.getParameter("dictionary");
     String normalization = request.getParameter("normalization");
-    String resultPage = request.getParameter("resultPage");
+    String normalizationType = request.getParameter("normalizationType");
+    String resultPageNumber = request.getParameter("resultPageNumber");
+    String resultPageSize = request.getParameter("resultPageSize");
     if (query == null) 
       query = "a*";
+    boolean isRangeQuery = false; 
+    if (query.endsWith("*"))
+      isRangeQuery = true;
+    if (queryDisplay == null)
+      queryDisplay = query;
     if (language == null)
       language = "eng";
     if (inputType == null || ! (inputType.equals("form") || inputType.equals("lemma")))
       inputType = "form";
-    if (outputFormat == null || ! (outputFormat.equals("xml") || outputFormat.equals("html")))
+    if (outputFormat == null || ! (outputFormat.equals("xml") || outputFormat.equals("html") || outputFormat.equals("htmlFragment")))
       outputFormat = "xml";
-    if (outputType == null || ! (outputType.equals("compact") || outputType.equals("full")))
-      outputType = "compact";
+    ArrayList<String> outputTypes = new ArrayList<String>();
+    if (outputTypesArray == null) {
+      outputTypes.add("allCompact");
+    } else if (isRangeQuery) {
+      outputTypes.add("dictCompact");
+    } else {
+      outputTypes = new ArrayList<String>(Arrays.asList(outputTypesArray));
+    }
     if (normalization == null || ! (normalization.equals("none") || normalization.equals("reg") || normalization.equals("reg norm")))
       normalization = "norm";
+    if (normalizationType == null || ! (normalizationType.equals("display") || normalizationType.equals("dictionary")))
+      normalizationType = "dictionary";
     String xmlDict = "all";
     if (dictionary != null)
       xmlDict = dictionary;
-    int pn = 1;
-    if (resultPage != null) 
-      pn = new Integer(resultPage);
-    boolean isRangeQuery = false; 
-    if (query.endsWith("*"))
-      isRangeQuery = true;
-    String xmlQueryString = "<query><name>" + query + "</name>" + "<language>" + language + "</language>" + "<inputType>" + inputType + "</inputType>" + 
-      "<outputFormat>" + outputFormat + "</outputFormat>" + "<outputType>" + outputType + "</outputType>" + "<dictionary>" + xmlDict + "</dictionary>" + 
-      "<normalization>" + normalization + "</normalization>" + "</query>";
+    int pageNumber = 1;
+    int pageSize = 50;
+    if (resultPageNumber != null) 
+      pageNumber = new Integer(resultPageNumber);
+    if (resultPageSize != null) 
+      pageSize = new Integer(resultPageSize);
+    String xmlQueryString = "<query>";
+    xmlQueryString = xmlQueryString + "<name>" + query + "</name>";
+    xmlQueryString = xmlQueryString + "<display>" + queryDisplay + "</display>";
+    xmlQueryString = xmlQueryString + "<language>" + language + "</language>";
+    xmlQueryString = xmlQueryString + "<inputType>" + inputType + "</inputType>";
+    xmlQueryString = xmlQueryString +  "<outputFormat>" + outputFormat + "</outputFormat>";
+    xmlQueryString = xmlQueryString + "<outputTypes>" + outputTypes + "</outputTypes>";
+    xmlQueryString = xmlQueryString + "<dictionary>" + xmlDict + "</dictionary>"; 
+    xmlQueryString = xmlQueryString + "<normalization>" + normalization + "</normalization>";
+    xmlQueryString = xmlQueryString + "<normalizationType>" + normalizationType + "</normalizationType>";
+    if (isRangeQuery) {
+      xmlQueryString = xmlQueryString + "<resultPageNumber>" + pageNumber + "</resultPageNumber>";
+      xmlQueryString = xmlQueryString + "<resultPageSize>" + pageSize + "</resultPageSize>";
+    }
+    xmlQueryString = xmlQueryString + "</query>";
     try {
       if (outputFormat.equals("xml"))
         response.setContentType("text/xml");
-      else if (outputFormat.equals("html"))
+      else if (outputFormat.equals("html") || outputFormat.equals("htmlFragment"))
         response.setContentType("text/html");
       else 
         response.setContentType("text/xml");
       PrintWriter out = response.getWriter();
       if (query == null || query.isEmpty()) {
-        out.print("request parameter query is empty. Please specify a query.");
+        out.print("request parameter \"query\" is empty. Please specify a query.");
         out.close();
         return;
       }
@@ -94,23 +125,34 @@
       if (isRangeQuery) {
         String queryTmp = query.substring(0, query.length() - 1); // without last star
         if (dictionary != null)
-          dictionaries = lexHandler.getLexEntriesByLexiconBeginningWith(dictionary, queryTmp, pn);
+          dictionaries = lexHandler.getLexEntriesByLexiconBeginningWith(dictionary, queryTmp, pageNumber, pageSize);
         else 
-          dictionaries = lexHandler.getLexEntriesBeginningWith(language, queryTmp, pn);
+          dictionaries = lexHandler.getLexEntriesBeginningWith(language, queryTmp, pageNumber, pageSize);
       } else {
-        lemmas = lexHandler.getLemmas(query, inputType, language, normalization);
-        dictionaries = lexHandler.getLexEntries(lemmas, language, dictionary);
+        String lang = language;
+        if (dictionary != null) {
+          Lexicon lexicon = Lexica.getInstance().getLexicon(dictionary);
+          if (lexicon != null)
+            lang = lexicon.getSourceLanguage();
+        }
+        int normMode = Normalizer.DICTIONARY;
+        if (normalization.equals("none"))
+          normMode = Normalizer.NONE;
+        else if (normalizationType.equals("display"))
+          normMode = Normalizer.DISPLAY;
+        lemmas = lexHandler.getLemmas(query, inputType, lang, normMode);
+        dictionaries = lexHandler.getLexEntries(lemmas, lang, dictionary, query);
       }
       String baseUrl = ServletUtil.getInstance().getBaseUrl(request);
       Date end = new Date();
       String elapsedTime = String.valueOf(end.getTime() - begin.getTime());
       String result = "";
       if (outputFormat == null || outputFormat.equals("xml"))
-        result = createXmlOutputString(query, lemmas, dictionaries, outputType, baseUrl, xmlQueryString, elapsedTime);
-      else if (outputFormat.equals("html"))
-        result = createHtmlOutputString(query, lemmas, dictionaries, outputType, elapsedTime);
+        result = createXmlOutputString(query, lemmas, dictionaries, outputTypes, baseUrl, xmlQueryString, elapsedTime);
+      else if (outputFormat.equals("html") || outputFormat.equals("htmlFragment"))
+        result = createHtmlOutputString(query, queryDisplay, language, lemmas, dictionaries, pageNumber, pageSize, isRangeQuery, outputFormat, outputTypes, elapsedTime);
       else 
-        result = createXmlOutputString(query, lemmas, dictionaries, outputType, baseUrl, xmlQueryString, elapsedTime);
+        result = createXmlOutputString(query, lemmas, dictionaries, outputTypes, baseUrl, xmlQueryString, elapsedTime);
       out.print(result);
       out.close();
     } catch (ApplicationException e) { 
@@ -122,12 +164,30 @@
     
   }
   
-  private String createXmlOutputString(String query, ArrayList<Lemma> lemmas, ArrayList<Lexicon> lexicons, String outputType, String baseUrl, String xmlQueryString, String elapsedTime) {
+  private String createXmlOutputString(String query, ArrayList<Lemma> lemmas, ArrayList<Lexicon> lexicons, ArrayList<String> outputTypes, String baseUrl, String xmlQueryString, String elapsedTime) {
+    boolean outputTypeMorphCompact = false; 
+    if (outputTypes.contains("allCompact") || outputTypes.contains("morphCompact"))
+      outputTypeMorphCompact = true;
+    boolean outputTypeMorphFull = false; 
+    if (outputTypes.contains("allFull") || outputTypes.contains("morphFull"))
+      outputTypeMorphFull = true;
+    boolean outputTypeDictCompact = false; 
+    if (outputTypes.contains("allCompact") || outputTypes.contains("dictCompact"))
+      outputTypeDictCompact = true;
+    boolean outputTypeDictFull = false; 
+    if (outputTypes.contains("allFull") || outputTypes.contains("dictFull"))
+      outputTypeDictFull = true;
+    boolean outputTypeWikiCompact = false; 
+    if (outputTypes.contains("allCompact") || outputTypes.contains("wikiCompact"))
+      outputTypeWikiCompact = true;
+    boolean outputTypeWikiFull = false; 
+    if (outputTypes.contains("allFull") || outputTypes.contains("wikiFull"))
+      outputTypeWikiFull = true;
     String result = "<result>";
     result = result + "<provider>" + "MPIWG MPDL language technology service (see: " + "" + baseUrl + "), Max Planck Institute for the History of Science, Berlin." + "</provider>";
     result = result + xmlQueryString;
     result = result + "<elapsed-time-ms>" + elapsedTime + "</elapsed-time-ms>";
-    if (lemmas != null && ! lemmas.isEmpty()) {
+    if ((outputTypeMorphCompact || outputTypeMorphFull) && lemmas != null && ! lemmas.isEmpty()) {
       result = result + "<morphology>";
       for (int i=0; i<lemmas.size(); i++) {
         Lemma lemma = lemmas.get(i);
@@ -135,7 +195,7 @@
         String language = lemma.getLanguage();
         result = result + "<lemma>";
         result = result + "<name>" + lemmaName + "</name>";
-        if (outputType != null && outputType.equals("full")) {
+        if (outputTypeMorphFull) {
           String lemmaProvider = lemma.getProvider();
           result = result + "<provider>" + lemmaProvider + "</provider>";
           result = result + "<language>" + language + "</language>";
@@ -147,7 +207,7 @@
           String remoteUrl = "http://www.perseus.tufts.edu/hopper/morph?l=" + lemmaName + "&amp;la=" + "greek";
           result = result + "<remoteUrl>" + remoteUrl + "</remoteUrl>";
         }
-        if (outputType != null && outputType.equals("full")) {
+        if (outputTypeMorphFull) {
           ArrayList<Form> forms = lemma.getFormsList();
           Collections.sort(forms);
           if (forms != null && ! forms.isEmpty()) {
@@ -169,20 +229,24 @@
       }
       result = result + "</morphology>";
     }
-    if (lexicons != null) {
+    if ((outputTypeDictCompact || outputTypeDictFull) && lexicons != null) {
       result = result + "<dictionaries>";
       for (int i=0; i<lexicons.size(); i++) {
         Lexicon lexicon = lexicons.get(i);
-        result = result + lexicon.toXmlString();
+        if (outputTypeDictFull)
+          result = result + lexicon.toXmlString();
+        else if (outputTypeDictCompact)
+          result = result + lexicon.toXmlStringCompact();
       }
       result = result + "</dictionaries>";
     }
-    if (outputType != null && outputType.equals("full") && lemmas != null && ! lemmas.isEmpty()) {
+    if ((outputTypeWikiCompact || outputTypeWikiFull) && lemmas != null && ! lemmas.isEmpty()) {
       result = result + "<wikipedia>";
+      String language = null;
       for (int i=0; i<lemmas.size(); i++) {
         Lemma lemma = lemmas.get(i);
         String lemmaName = lemma.getLemmaName();
-        String language = lemma.getLanguage();
+        language = Language.getInstance().getLanguageId(lemma.getLanguage());
         result = result + "<article>";
         result = result + "<name>" + lemmaName + "</name>";
         String wikiHrefExact = "http://" + language + ".wikipedia.org/wiki/" + lemmaName;
@@ -191,65 +255,137 @@
         result = result + "<remoteUrlSearch>" + wikiHrefSearch + "</remoteUrlSearch>";
         result = result + "</article>";
       }
+      if (language != null && Language.getInstance().isGerman(language) && query != null) {
+        String[] queryFormNames = query.split(" ");
+        for (int j=0; j<queryFormNames.length; j++) {
+          String queryFormName = queryFormNames[j];          
+          result = result + "<article>";
+          result = result + "<name>" + queryFormName + "</name>";
+          String wikiHrefExact = "http://" + language + ".wikipedia.org/wiki/" + queryFormName;
+          String wikiHrefSearch = "http://" + language + ".wikipedia.org/wiki/index.php?search=" + queryFormName;
+          result = result + "<remoteUrl>" + wikiHrefExact + "</remoteUrl>";
+          result = result + "<remoteUrlSearch>" + wikiHrefSearch + "</remoteUrlSearch>";
+          result = result + "</article>";
+        }
+      }
       result = result + "</wikipedia>";
     }
     result = result + "</result>";
     return result;
   }
   
-  private String createHtmlOutputString(String query, ArrayList<Lemma> lemmas, ArrayList<Lexicon> lexicons, String outputType, String elapsedTime) {
+  private String createHtmlOutputString(String query, String queryDisplay, String language, ArrayList<Lemma> lemmas, ArrayList<Lexicon> lexicons, int pageNumber, int pageSize, boolean isRangeQuery, String outputFormat, ArrayList<String> outputTypes, String elapsedTime) {
+    boolean outputTypeMorphCompact = false; 
+    if (outputTypes.contains("allCompact") || outputTypes.contains("morphCompact"))
+      outputTypeMorphCompact = true;
+    boolean outputTypeMorphFull = false; 
+    if (outputTypes.contains("allFull") || outputTypes.contains("morphFull"))
+      outputTypeMorphFull = true;
+    boolean outputTypeDictCompact = false; 
+    if (outputTypes.contains("allCompact") || outputTypes.contains("dictCompact"))
+      outputTypeDictCompact = true;
+    boolean outputTypeDictFull = false; 
+    if (outputTypes.contains("allFull") || outputTypes.contains("dictFull"))
+      outputTypeDictFull = true;
+    boolean outputTypeWikiCompact = false; 
+    if (outputTypes.contains("allCompact") || outputTypes.contains("wikiCompact"))
+      outputTypeWikiCompact = true;
+    boolean outputTypeWikiFull = false; 
+    if (outputTypes.contains("allFull") || outputTypes.contains("wikiFull"))
+      outputTypeWikiFull = true;
     String result = "";
     result = result + "<html>";
     result = result + "<head>";
-    result = result + "<title>Word information for: \"" + query + "\"</title>";
+    result = result + "<title>WordInfo for: \"" + queryDisplay + "\"</title>";
+    result = result + "<link rel=\"stylesheet\" type=\"text/css\" href=\"/mpiwg-mpdl-lt-web/css/getDictionaryEntries.css\"/>";
+    result = result + getJavascriptFunctions();
     result = result + "</head>";
-    result = result + "<body>";
+    result = result + "<body class=\"body\">";
     result = result + "<table align=\"right\" valign=\"top\">";
     result = result + "<td>[<i>This is a MPIWG MPDL language technology service</i>] <a href=\"/mpiwg-mpdl-lt-web/index.html\"><img src=\"/mpiwg-mpdl-lt-web/images/info.png\" valign=\"bottom\" width=\"15\" height=\"15\" border=\"0\" alt=\"MPIWG MPDL language technology service\"/></a></td>";
     result = result + "</table>";
     result = result + "<p/>";
-    result = result + "<h1>Word information for: \"" + query + "\"</h1>";
-    if (lemmas != null && ! lemmas.isEmpty()) {
-      result = result + "<h3>Morphology</h3>";
+    result = result + "<div class=\"title\">WordInfo</div>";
+    
+    result = result + "<form name=\"getDictionaryEntries\" action=\"GetDictionaryEntries\" method=\"get\">";
+    result = result + "Query: <input name=\"query\" class=\"query\" type=\"text\" size=\"20\" value=\"" + query + "\"/>";
+    String htmlSelectBox = Language.getInstance().getHtmlSelectBox(language);
+    result = result + " Language: " + htmlSelectBox;
+    result = result + "<input type=\"hidden\" name=\"outputFormat\" value=\"" + outputFormat + "\"/>";
+    for (int i=0; i<outputTypes.size(); i++) {
+      String type = outputTypes.get(i);
+      result = result + "<input type=\"hidden\" name=\"outputType\" value=\"" + type + "\"/>";
+    }
+    result = result + " <button type=\"submit\" onclick=\"var query = document.getDictionaryEntries.query.value; if(query.substring(query.length-1, query.length) == '*') {document.getDictionaryEntries.outputType.value = 'dictCompact';}\">Query</button>";
+    result = result + "</form>";
+    result = result + "<hr/>";
+
+    if ((outputTypeMorphCompact || outputTypeMorphFull) && lemmas != null && ! lemmas.isEmpty()) {
+      result = result + "<span class=\"inputType\">Morphology</span>";
+      result = result + "<span  class=\"tree\">";
       result = result + "<ul>";
-      result = result + "<p/>";
+      result = result + "<li>" + "<b>" + "Lemmata" + "</b>";
+      result = result + "<ul>";
       for (int i=0; i<lemmas.size(); i++) {
         Lemma lemma = lemmas.get(i);
         String lemmaName = lemma.getLemmaName();
-        String language = lemma.getLanguage();
-        result = result + "<li>";
-        result = result + lemmaName;
-        if (outputType != null && outputType.equals("full")) {
+        String providerText = "";
+        String externalLinkText = "";
+        String formsText = "";
+        if (outputTypeMorphFull) {
           String lemmaProvider = lemma.getProvider();
-          result = result + " (data provider: " + lemmaProvider + ")";
+          providerText = " (data provider: " + lemmaProvider + ")";
         }
         if (Language.getInstance().isArabic(language) || Language.getInstance().isLatin(language))
-          result = result + " (external link: <a href=\"http://www.perseus.tufts.edu/hopper/morph?l=" + lemmaName + "&amp;la=" + language + "\">" + lemmaName + "</a>)";
+          externalLinkText = " (external link: <a href=\"http://www.perseus.tufts.edu/hopper/morph?l=" + lemmaName + "&amp;la=" + language + "\">" + lemmaName + "</a>)";
         else if (Language.getInstance().isGreek(language))
-          result = result + " (external link: <a href=\"http://www.perseus.tufts.edu/hopper/morph?l=" + lemmaName + "&amp;la=" + "greek" + "\">" + lemmaName + "</a>)";
-        if (outputType != null && outputType.equals("full")) {
-          ArrayList<Form> forms = lemma.getFormsList();
-          Collections.sort(forms);
-          if (forms != null && ! forms.isEmpty()) {
-            result = result + "<ul>";
-            for (int j=0; j<forms.size(); j++) {
-              Form f = forms.get(j);
-              String formName = f.getFormName();
-              String formProvider = f.getProvider();
-              result = result + formName + " (data provider: " + formProvider + "), ";
-            }
-            result = result.substring(0, result.length() - 2);  // without last comma and blank
-            result = result + "</ul>";
+          externalLinkText = " (external link: <a href=\"http://www.perseus.tufts.edu/hopper/morph?l=" + lemmaName + "&amp;la=" + "greek" + "\">" + lemmaName + "</a>)";
+        ArrayList<Form> forms = lemma.getFormsList();
+        Collections.sort(forms);
+        if (forms != null && ! forms.isEmpty()) {
+          formsText = formsText + "<ul>";
+          formsText = formsText + "<b>" + "Forms: " + "</b>";
+          for (int j=0; j<forms.size(); j++) {
+            Form f = forms.get(j);
+            String formName = f.getFormName();
+            String formProvider = f.getProvider();
+            formsText = formsText + formName + " (data provider: " + formProvider + "), ";
           }
+          formsText = formsText.substring(0, formsText.length() - 2);  // without last comma and blank
+          formsText = formsText + "</ul>";
         }
-        result = result + "</li>";
+        if (outputTypeMorphFull) {
+          result = result + "<li><input type=\"checkbox\" checked=\"checked\"/><label>" + lemmaName + providerText + externalLinkText + "</label>" + formsText + "</li>";
+        } else if (outputTypeMorphCompact) { 
+          result = result + "<li><input type=\"checkbox\"/><label>" + "<a href=\"GetDictionaryEntries?query=" + lemmaName + "&language=" + language + "&inputType=lemma" + "&outputFormat=html" + "&outputType=morphFull" + "\">" + lemmaName + "</a>" + providerText + externalLinkText + "</label>" + formsText + "</li>";
+        }
       }
       result = result + "</ul>";
+      result = result + "</li>";
+      result = result + "</ul>";
+      result = result + "</span>";
     }
-    if (lexicons != null && ! lexicons.isEmpty()) {
-      result = result + "<h3>Dictionary</h3>";
+    if ((outputTypeDictCompact || outputTypeDictFull) && lexicons != null && ! lexicons.isEmpty()) {
+      if (isRangeQuery) {
+        int pageNumberUp = 1;
+        if (pageNumber > 1)
+          pageNumberUp = pageNumber - 1;
+        int pageNumberDown = pageNumber + 1;
+        int from = (pageNumber * pageSize) - pageSize + 1;
+        int to = pageNumber * pageSize;
+        result = result + "<table align=\"right\">";
+        result = result + "<tr>";
+        result = result + "<td valign=\"middle\">Page: </td>";
+        result = result + "<td valign=\"middle\"><a href=\"/mpiwg-mpdl-lt-web/lt/GetDictionaryEntries?query=" + query + "&amp;language=" + language + "&amp;resultPageNumber=" + pageNumberUp + "&amp;outputFormat=html\"><img alt=\"page up\" src=\"/mpiwg-mpdl-lt-web/images/left.gif\" height=\"20\" width=\"20\"></a></td>";
+        result = result + "<td valign=\"middle\">" + pageNumber + "</td>";
+        result = result + "<td valign=\"middle\"><a href=\"/mpiwg-mpdl-lt-web/lt/GetDictionaryEntries?query=" + query + "&amp;language=" + language + "&amp;resultPageNumber=" + pageNumberDown + "&amp;outputFormat=html\"><img alt=\"page down\" src=\"/mpiwg-mpdl-lt-web/images/right.gif\" height=\"20\" width=\"20\"></a></td>";
+        result = result + "<td valign=\"middle\">(" + from + " - " + to + ")</td>";
+        result = result + "</tr>";
+        result = result + "</table>";
+      } 
+      result = result + "<span class=\"inputType\">Dictionary</span>";
+      result = result + "<span  class=\"tree\">";
       result = result + "<ul>";
-      result = result + "<p/>";
       for (int i=0; i<lexicons.size(); i++) {
         Lexicon lexicon = lexicons.get(i);
         result = result + "<li>";
@@ -283,34 +419,50 @@
           }
           String formName = entry.getFormName();
           String dictName = lexicon.getName();
-          if (outputType != null && outputType.equals("full")) {
-            result = result + "<li>" + "<b>" + formName + "</b><ul><li>" + entryContent + "</li></ul></li>";
-          } else if (outputType != null && outputType.equals("compact")) {
-            result = result + "<li>" + "<a href=\"GetDictionaryEntries?query=" + formName + "&dictionary=" + dictName + "&outputFormat=html" + "&outputType=full" + "\">" + formName + "</a></li>";
+          if (outputTypeDictFull) {
+            result = result + "<li><input type=\"checkbox\" checked=\"checked\"/><label><b>" + formName + "</b></label><ul><li>" + entryContent + "</li></ul></li>";
+          } else if (outputTypeDictCompact) {
+            result = result + "<li><input type=\"checkbox\"/><label>" + "<a href=\"GetDictionaryEntries?query=" + formName + "&language=" + language + "&dictionary=" + dictName + "&inputType=lemma" + "&outputFormat=html" + "&outputType=dictFull" + "\">" + formName + "</a>" + "</label><ul><li>" + entryContent + "</li></ul></li>";
           }
         }
         result = result + "</ul>";
         result = result + "</li>";  // lexicon entry
       }
       result = result + "</ul>";
-      result = result + "</p>";
+      result = result + "</span>";
     }
-    if (outputType != null && outputType.equals("full") && lemmas != null && ! lemmas.isEmpty()) {
-      result = result + "<h3>Wikipedia</h3>";
+    if ((outputTypeWikiCompact || outputTypeWikiFull) && lemmas != null && ! lemmas.isEmpty()) {
+      String langId = Language.getInstance().getLanguageId(language);
+      String wikiUrl = langId + ".wikipedia.org";
+      result = result + "<span class=\"inputType\">Wikipedia</span>";
+      result = result + "<span  class=\"tree\">";
       result = result + "<ul>";
-      result = result + "<p/>";
+      result = result + "<li>" + "<b>" + wikiUrl + "</b>";
+      result = result + "<ul>";
       for (int i=0; i<lemmas.size(); i++) {
         Lemma lemma = lemmas.get(i);
         String lemmaName = lemma.getLemmaName();
-        String language = lemma.getLanguage();
-        result = result + "<li>";
-        String wikiHrefExact = "http://" + language + ".wikipedia.org/wiki/" + lemmaName;
-        String wikiHrefSearch = "http://" + language + ".wikipedia.org/wiki/index.php?search=" + lemmaName;
-        result = result + "<b>Article: </b>External link: <a href=\"" + wikiHrefExact + "\">" + lemmaName + "</a> (or search for <a href=\"" + wikiHrefSearch + "\">" + lemmaName + "</a>)";
-        result = result + "</li>";
+        String wikiHrefExact = "http://" + wikiUrl + "/wiki/" + lemmaName;
+        String wikiHrefSearch = "http://" + wikiUrl + "/wiki/index.php?search=" + lemmaName;
+        result = result + "<li><input type=\"checkbox\" checked=\"checked\"/><label>" + "External link: <a href=\"" + wikiHrefExact + "\">" + lemmaName + "</a> (or search for <a href=\"" + wikiHrefSearch + "\">" + lemmaName + "</a>)" + "</label>" + "</li>";
+      }
+      if (language != null && Language.getInstance().isGerman(language) && query != null) {
+        String[] queryFormNames = query.split(" ");
+        for (int j=0; j<queryFormNames.length; j++) {
+          String queryFormName = queryFormNames[j];          
+          result = result + "<li>";
+          String wikiHrefExact = "http://" + wikiUrl + "/wiki/" + queryFormName;
+          String wikiHrefSearch = "http://" + wikiUrl + "/wiki/index.php?search=" + queryFormName;
+          result = result + "<li><input type=\"checkbox\" checked=\"checked\"/><label>" + "External link: <a href=\"" + wikiHrefExact + "\">" + queryFormName + "</a> (or search for <a href=\"" + wikiHrefSearch + "\">" + queryFormName + "</a>)" + "</label>" + "</li>";
+          result = result + "</li>";
+        }
       }
       result = result + "</ul>";
+      result = result + "</li>";
+      result = result + "</ul>";
+      result = result + "</span>";
     }
+    result = result + "<p/>";
     result = result + "[* external links may not function]";
     result = result + "<hr/>";
     result = result + "<p/>";
@@ -320,5 +472,14 @@
     return result;
   }
 
-  
+  private String getJavascriptFunctions() {
+    String result = "<script type=\"text/javascript\">";
+    result = result + "<!-- ";
+    result = result + "function strEndsWith(str, suffix) {";
+    result = result + "  return str.match(suffix + \"$\") == suffix;";
+    result = result + "}";
+    result = result + " -->";
+    result = result + "</script>";
+    return result;
+  }
 }
--- a/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetForms.java	Wed Dec 14 12:48:43 2011 +0100
+++ b/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetForms.java	Wed Dec 14 12:49:06 2011 +0100
@@ -17,6 +17,7 @@
 import de.mpg.mpiwg.berlin.mpdl.lt.dict.db.LexHandler;
 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Form;
 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Lemma;
+import de.mpg.mpiwg.berlin.mpdl.lt.text.norm.Normalizer;
 
 public class GetForms extends HttpServlet {
   private static final long serialVersionUID = 1L;
@@ -52,6 +53,9 @@
       outputType = "compact";
     if (normalization == null || ! (normalization.equals("none") || normalization.equals("reg") || normalization.equals("reg norm")))
       normalization = "norm";
+    int normalizationType = Normalizer.DICTIONARY;
+    if (normalization != null && normalization.equals("none"))
+      normalizationType = Normalizer.NONE;
 
     String xmlQueryString = "<query><name>" + query + "</name>" + "<language>" + language + "</language>" +  
       "<outputFormat>" + outputFormat + "</outputFormat>" + "<outputType>" + outputType + "</outputType>" + "<normalization>" + normalization + "</normalization>" + "</query>";
@@ -68,7 +72,7 @@
         out.close();
         return;
       }
-      ArrayList<Lemma> lemmas = lexHandler.getLemmas(query, "lemma", language, normalization);
+      ArrayList<Lemma> lemmas = lexHandler.getLemmas(query, "lemma", language, normalizationType);
       Hashtable<String, Form> formsHashtable = new Hashtable<String, Form>();
       ArrayList<Form> forms = new ArrayList<Form>();
       if (lemmas != null && ! lemmas.isEmpty()) {
--- a/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetLemmas.java	Wed Dec 14 12:48:43 2011 +0100
+++ b/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/GetLemmas.java	Wed Dec 14 12:49:06 2011 +0100
@@ -17,6 +17,7 @@
 import de.mpg.mpiwg.berlin.mpdl.lt.general.Language;
 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Form;
 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Lemma;
+import de.mpg.mpiwg.berlin.mpdl.lt.text.norm.Normalizer;
 
 public class GetLemmas extends HttpServlet {
   private static final long serialVersionUID = 1L;
@@ -55,6 +56,9 @@
       outputType = "compact";
     if (normalization == null || ! (normalization.equals("none") || normalization.equals("reg") || normalization.equals("reg norm")))
       normalization = "norm";
+    int normalizationType = Normalizer.DICTIONARY;
+    if (normalization != null && normalization.equals("none"))
+      normalizationType = Normalizer.NONE;
 
     String xmlQueryString = "<query><name>" + query + "</name>" + "<language>" + language + "</language>" + "<inputType>" + inputType + "</inputType>" + 
       "<outputFormat>" + outputFormat + "</outputFormat>" + "<outputType>" + outputType + "</outputType>" + "<normalization>" + normalization + "</normalization>" + "</query>";
@@ -71,7 +75,7 @@
         out.close();
         return;
       }
-      ArrayList<Lemma> lemmas = lexHandler.getLemmas(query, inputType, language, normalization);
+      ArrayList<Lemma> lemmas = lexHandler.getLemmas(query, inputType, language, normalizationType);
       String baseUrl = getBaseUrl(request);
       Date end = new Date();
       String elapsedTime = String.valueOf(end.getTime() - begin.getTime());
--- a/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/Tokenize.java	Wed Dec 14 12:48:43 2011 +0100
+++ b/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/Tokenize.java	Wed Dec 14 12:49:06 2011 +0100
@@ -23,6 +23,7 @@
 import de.mpg.mpiwg.berlin.mpdl.lt.dict.app.Lexicon;
 import de.mpg.mpiwg.berlin.mpdl.lt.dict.db.LexHandler;
 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Lemma;
+import de.mpg.mpiwg.berlin.mpdl.lt.text.norm.Normalizer;
 import de.mpg.mpiwg.berlin.mpdl.lt.text.tokenize.Token;
 import de.mpg.mpiwg.berlin.mpdl.lt.text.tokenize.Tokenizer;
 import de.mpg.mpiwg.berlin.mpdl.lt.text.tokenize.XmlTokenizer;
@@ -106,8 +107,8 @@
           LexHandler lexHandler = LexHandler.getInstance();
           for (int i = 0; i < tokens.size(); i++) {
             String token = tokens.get(i);
-            ArrayList<Lemma> lemmas = lexHandler.getLemmas(token, "form", language, "none");
-            ArrayList<Lexicon> dictionaries = lexHandler.getLexEntries(lemmas, language, null);
+            ArrayList<Lemma> lemmas = lexHandler.getLemmas(token, "form", language, Normalizer.NONE);
+            ArrayList<Lexicon> dictionaries = lexHandler.getLexEntries(lemmas, language, null, null);
             tokensDictionaries.put(token, dictionaries);
           }
         }
--- a/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/Transcode.java	Wed Dec 14 12:48:43 2011 +0100
+++ b/software/mpdl-services/mpiwg-mpdl-lt-web/src/de/mpg/mpiwg/berlin/mpdl/servlets/lt/Transcode.java	Wed Dec 14 12:49:06 2011 +0100
@@ -47,6 +47,11 @@
         out.close();
         return;
       }
+      if (destEncoding == null || destEncoding.isEmpty()) {
+        out.print("request parameter \"destEncoding\" is empty. Please specify \"destEncoding\"");
+        out.close();
+        return;
+      }
       if (srcEncoding.equals("buckwalter") && destEncoding.equals("unicode")) {
         result = transcoder.transcodeFromBuckwalter2Unicode(inputString);
       } else if (srcEncoding.equals("betacode") && destEncoding.equals("unicode")) {
@@ -55,6 +60,8 @@
         result = transcoder.transcodeFromUnicode2BetaCode(inputString);
       } else if (srcEncoding.equals("unicode") && destEncoding.equals("buckwalter")) {
         result = transcoder.transcodeFromUnicode2Buckwalter(inputString);
+      } else {
+        result = "your combination of \"srcEncoding\" and \"destEncoding\" is not yet supported";
       }
       if (result != null)
         out.print(result);