5

I would like to translate the subject(MeSH) terms displayed in item-view.xsl in the DSPace instance that I'm maintaining if the language is switched. Previously I am using the code below (I added this in XSLUtils.java class) to lookup to Babelmesh site and translate it on the fly.

    public static String lookupBabelMeSH(String term, String lang) {
    try {
        URLConnection babelMeshConn = (new URL("https://babelmesh.nlm.nih.gov/mesh_trans.php?oterm=" + URLEncoder.encode(term, "UTF-8") + "&in=ENG&out=" + lang)).openConnection();
        babelMeshConn.setConnectTimeout(5000);
        babelMeshConn.setReadTimeout(5000);

        BufferedReader in = new BufferedReader(new InputStreamReader(babelMeshConn.getInputStream(), "UTF-8"));
        String value = in.readLine();
        in.close();

        if (!StringUtils.isEmpty(value)) {
            return value;
        }
    } catch (MalformedURLException mue) {

    } catch (IOException ioe) {

    }

    return null;
}

I then used it in item-view.xsl like this:

  <xsl:choose>
    <xsl:when test="$active-locale!='en'">
      <xsl:variable name="current-locale">
        <xsl:if test="$active-locale='fr'">
          <xsl:text>FRE</xsl:text>
        </xsl:if>
        <xsl:if test="$active-locale='zh'">
          <xsl:text>CHN</xsl:text>
        </xsl:if>
      </xsl:variable>
      <xsl:variable name="translation">
        <xsl:value-of select="util:lookupBabelMeSH(node(),$current-locale)"/>
      </xsl:variable>
    <xsl:choose>
        <xsl:when test="$translation=''">
          <xsl:value-of select="node()"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$translation"/>
        </xsl:otherwise>
     </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="node()"/>
    </xsl:otherwise>
  </xsl:choose>

Now, I would like to translate the text without calling BabelMesh site everytime the language is switched since there's a limit to the number of requests. Also, since the url to BabelMesh is hardcoded, any changes to BabelMesh service will break the rendering of the translation. I only need to translate the terms into chinese and french. I have the translations located in [dspace]/config/mesh directory. The files are named mterms_fr and mterms_zh for french and chinese translations respectively.

The contents of these files looked like these:

mterms_fr

Acanthocheilonemiasis::acanthocheilonemiase
Acanthocytes::ACANTHOCYTE
Acantholysis::ACANTHOLYSE
Acanthoma::ACANTHOME
Acanthopodina::ACANTHOPODINA
Acanthosis Nigricans::ACANTHOSIS NIGRICANS
Acarbose::ACARBOSE
Acari::ACARIEN
Acaricides::Acaricides
Acaridae::ACARIDAE
Acatalasia::ACATALASIE
Accelerated Idioventricular Rhythm::RYTHME IDIOVENTRICULAIRE ACCELERE
Acceleration::ACCELERATION

mterms_zh

Acanthocheilonemiasis::棘唇虫病
Acanthocytes::棘形红细胞
Acantholysis::皮肤棘层松解
Acanthoma::棘皮瘤
Acanthopodina::Acanthopodina
Acanthosis Nigricans::Acanthosis Nigricans
Acarbose::Acarbose
Acari::Acari
Acaricides::Acaricides
Acaridae::Acaridae
Acatalasia::Acatalasia
Accelerated Idioventricular Rhythm::Accelerated Idioventricular Rhythm
Acceleration::加速度

If you noticed, the :: is the separator between the english terms and the translations. If there's no translation for that term, the english term is retained (eg Acaricides).

So would it be possible to just lookup to these files from the [dspace]/config/mesh directory and do the translation on-the-fly?

EDIT

I would like to add that if ever the term is not found in the translation file, it should be returned as is (eg some random text should return some random text) since it is expected that I have no control to what users will input in the subject field (ie via batch import).

Thanks in advance!

euler
  • 1,401
  • 2
  • 18
  • 39

1 Answers1

3

You can try something like this (added to XSLUtils.java):

        private static Properties chinnese = null;
                 private static Properties french = null;

            static{


               try {
               chinnese = new Properties();
               String mterms_zhPath=ConfigurationManager.getProperty("mterms_zh.path");
               chinnese.load(new InputStreamReader(new FileInputStream(new File(mterms_zhPath)), "UTF8"));
               french = new Properties();
               String mterms_frPath=ConfigurationManager.getProperty("mterms_fr.path");     
               french.load(new InputStreamReader(new FileInputStream(new File(mterms_frPath)), "UTF8"));
               } catch (UnsupportedEncodingException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
               } catch (FileNotFoundException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
               } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
               }
            }

            public static String lookupMeSH(String term, String lang) {
               String translated=null;
               if("zh".equals(lang)){
                   translated=chinnese.getProperty(term);
               }else if("fr".equals(lang)){
                   translated=french.getProperty(term);
               }
               return translated;
            }

At dspace.cfg you should add the path of files:

mterms_zh.path= /put/the/file/path
mterms_fr.path=/home/dspace_instalation/config/mterms_fr

check langs comparations and file adquisition.

then change:

<xsl:value-of select="util:lookupBabelMeSH(node(),$current-locale)"/>

for

<xsl:value-of select="util:lookupMeSH(node(),$current-locale)"/>

at the xsl

And replace the files separator from "::" to "="

ADDED full running class:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Properties;


public class Test3 {
    private static Properties chinnese = null;
    private static Properties french = null;

static{

          chinnese = new Properties();
          try {
          String mterms_zhPath="D:/mterms_fr";     
          chinnese.load(new InputStreamReader(new FileInputStream(new File(mterms_zhPath)), "UTF8"));
          french = new Properties();
          String mterms_frPath="D:/mterms_fr";     
          french.load(new InputStreamReader(new FileInputStream(new File(mterms_frPath)), "UTF8"));
          } catch (UnsupportedEncodingException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          } catch (FileNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          }
        }

        public static String lookupMeSH(String term, String lang) {
          String translated=null;
          if("zh".equals(lang)){
              translated=chinnese.getProperty(term);
          }else if("fr".equals(lang)){
              translated=french.getProperty(term);
          }
          return translated;
        }
        public static void main (String [] args) { 
          //  Test3 test3=new Test3();
            //XSLUtils s = new XSLUtils();
            System.out.println(lookupMeSH("Acari", "fr")); }
}
Adán
  • 381
  • 3
  • 14
  • Adán, thanks for this. I'm having errors in my IDE though. Particularly in the `getClass()` portion where it says "Non static method 'getClass()' cannot be referenced from a static context". Also, how can this method locate the mesh terms? I'm actually expecting that `ConfigurationManager.propertyNames` will be used to reference the files. Please advice and thanks in advance. – euler Nov 16 '16 at 07:16
  • I changed the code and it compile, but i dont tried it. – Adán Nov 17 '16 at 17:48
  • Hi Adán. I've added this code for testing in my IDE: `public static void main (String [] args) { XSLUtils s = new XSLUtils();System.out.println(lookupMeSH("Health", "fr")); }` I also replaced the values of `String mterms_frPath` to the absolute path of the file. When I run the code, I received this error: `Exception in thread "main" java.lang.NullPointerException at org.dspace.app.xmlui.utils.XSLUtils.lookupMeSH(XSLUtils.java:145)` which is referring to this line of code: `translated=french.getProperty(term);`. It seems the contents of this file are not loaded. Thanks again for the help. – euler Nov 18 '16 at 03:56
  • 1
    thanks for the updated code. After running multiple tests with different terms, I discovered that the code does not work for terms that have spaces (eg `Accelerated Idioventricular Rhythm`). It returned `null`. – euler Nov 23 '16 at 11:19
  • 1
    try replacing whitespaces at terms files with \u0020. one two = value TO one\u0020two = value – Adán Nov 28 '16 at 10:44
  • Thanks Adán. Replacing spaces with `\u0020` did indeed worked for terms with spaces. Unfortunately, this only works if I run `XSLUtils.main()` but not when I tried it on my DSpace instance. I tried using absolute paths after using `ConfigurationManager.getProperty` did not work, and it's still not working. I'm starting to doubt if this is possible. I would gladly mark your answer as the accepted answer if this will work in my DSpace instance. Perhaps there is something that I might be missing and would be very glad to hear from you. Thanks again. – euler Nov 30 '16 at 06:12