001package org.hl7.fhir.utilities;
002
003/*
004  Copyright (c) 2011+, HL7, Inc.
005  All rights reserved.
006  
007  Redistribution and use in source and binary forms, with or without modification, 
008  are permitted provided that the following conditions are met:
009    
010   * Redistributions of source code must retain the above copyright notice, this 
011     list of conditions and the following disclaimer.
012   * Redistributions in binary form must reproduce the above copyright notice, 
013     this list of conditions and the following disclaimer in the documentation 
014     and/or other materials provided with the distribution.
015   * Neither the name of HL7 nor the names of its contributors may be used to 
016     endorse or promote products derived from this software without specific 
017     prior written permission.
018  
019  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
020  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
021  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
022  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
023  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
024  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
025  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
026  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
027  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
028  POSSIBILITY OF SUCH DAMAGE.
029  
030 */
031
032
033
034import java.io.File;
035import java.io.IOException;
036import java.util.Date;
037import java.util.HashMap;
038import java.util.HashSet;
039import java.util.Map;
040import java.util.Set;
041
042import javax.xml.parsers.DocumentBuilder;
043import javax.xml.parsers.DocumentBuilderFactory;
044import javax.xml.parsers.ParserConfigurationException;
045
046import org.hl7.fhir.utilities.xml.XMLUtil;
047import org.w3c.dom.Document;
048import org.w3c.dom.Element;
049import org.w3c.dom.Node;
050import org.xml.sax.SAXException;
051
052public class TranslatorXml implements TranslationServices {
053
054  
055  public class TranslatedTerm {
056    private Set<String> props = new HashSet<String>();
057    private Map<String, String> translations = new HashMap<String, String>();
058  }
059
060
061  private Map<String, TranslatedTerm> termsById = new HashMap<String, TranslatedTerm>();  
062  private Map<String, TranslatedTerm> termsByTerm = new HashMap<String, TranslatedTerm>();  
063  
064  public TranslatorXml(String filename) throws ParserConfigurationException, SAXException, IOException {
065    super();
066    load(filename);
067  }
068
069
070  private void load(String filename) throws ParserConfigurationException, SAXException, IOException {
071    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
072    factory.setNamespaceAware(false);
073    DocumentBuilder builder = factory.newDocumentBuilder();
074    Document xml = builder.parse(new File(filename)); 
075    Element e = XMLUtil.getFirstChild(xml.getDocumentElement());
076    while (e != null) {
077      load(e);
078      e = XMLUtil.getNextSibling(e);
079    }
080  }
081
082  private void load(Element e) {
083    TranslatedTerm t = new TranslatedTerm();
084    for (int i = 0; i < e.getAttributes().getLength(); i++) {
085      Node a = e.getAttributes().item(i);
086      String n = a.getNodeName();
087      if (n.equals("id"))
088        termsById.put(a.getTextContent(), t);
089      else if (a.getNodeValue().equals("true"))
090        t.props.add(n);
091    }
092    Element c = XMLUtil.getFirstChild(e);
093    while (c != null) {
094      String l = c.getAttribute("lang");
095      String s = c.getTextContent();
096      if (l.equals("en"))
097        termsByTerm.put(s, t);
098      t.translations.put(l, s);
099      c = XMLUtil.getNextSibling(c);
100    }    
101  }
102
103
104  private Map<String, String> getTranslations(String code) {
105    TranslatedTerm t = termsById.get(code);
106    if (t == null)
107      t = termsByTerm.get(code);
108    return t == null ? null : t.translations;
109  }
110
111  
112  @Override
113  public String translate(String context, String value, String targetLang) {
114    if (targetLang == null)
115      return value;
116    Map<String, String> t = getTranslations(value);
117    if (t == null)
118      return value;
119    if (t.containsKey(targetLang))
120      return t.get(targetLang);
121    return value;
122  }
123
124  @Override
125  public String translateAndFormat(String context, String lang, String value, Object... args) {
126    value = translate(context, value, lang);
127    return value == null ? "":  String.format(value, args);
128  }
129
130  @Override
131  public String translate(String context, String value) {
132    return null;    
133  }
134
135  @Override
136  public String toStr(float value) {
137    return null;
138  }
139
140  @Override
141  public String toStr(Date value) {
142    return null;
143  }
144
145
146  @Override
147  public Map<String, String> translations(String value) {
148    return getTranslations(value);
149  }
150
151
152  @Override
153  public Set<String> listTranslations(String category) {
154    Set<String> res = new HashSet<String>();
155    for (String s : termsById.keySet()) {
156      if (termsById.get(s).props.contains(category))
157        res.add(s);
158    }
159    return res;
160  }
161 
162}