All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openehr.am.template.TermMap Maven / Gradle / Ivy

The newest version!
/*
 * component:   "openEHR Java Reference Implementation"
 * description: "Class TermMap"
 * keywords:    "oet-parser"
 *
 * author:      "Rong Chen "
 * copyright:   "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden"
 * license:     "See notice at bottom of class"
 *
 * file:        "$URL$"
 * revision:    "$LastChangedRevision$"
 * last_change: "$LastChangedDate$"
 */

package org.openehr.am.template;

import java.io.*;
import java.util.*;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.openehr.rm.datatypes.text.CodePhrase;

/**
 * An in-memory term serving component that can be used as alternative
 * to full-blown terminology service. It can load from and write to text
 * file using the following syntax for each line. The path item is optional
 * and only required if different texts are needed for the same terminology
 * and code combination.
 * 
 * {terminology}::{code}::{text}[::{path}]
 * 
 * @author rong.chen
 *
 */
public class TermMap {

	public TermMap() {
		termMap = new TreeMap>>();
	}
	
	/**
	 * Loads an in-memory termMap by given file 
	 * 
	 * @param input
	 * @return
	 * @throws IOException
	 */	
	public static TermMap load(String filename) throws IOException {
		List lines = FileUtils.readLines(new File(filename), UTF8);
		return fromLines(lines);
	}
	
	/**
	 * Loads an in-memory termMap by given inputStream 
	 * 
	 * @param input
	 * @return
	 * @throws IOException
	 */
	public static TermMap load(InputStream input) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF8));
		String line = reader.readLine();
		List lines = new ArrayList();
		while(line != null) {
			lines.add(line);
			line = reader.readLine();
		}
		return fromLines(lines);		
	}
	
	/**
	 * Parses given lines and loads a termMap
	 * 
	 * @param lines
	 * @return
	 */
	static TermMap fromLines(List lines) {
		TermMap termMap = new TermMap();
		termMap.addAll(lines);
		return termMap;
	}
	
	/**
	 * Adds all content from given inputStream
	 * 
	 * @param input
	 * @throws Exception
	 */
	public void addAll(InputStream input) throws Exception {
		BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF8));
		String line = reader.readLine();
		List lines = new ArrayList();
		while(line != null) {
			lines.add(line);
			line = reader.readLine();
		}
		addAll(lines);
	}
	
	/**
	 * Adds all given lines into this termMap
	 * 
	 * @param lines
	 */
	public void addAll(List lines) {
		String text = null;
		String terminology = null;
		String code = null;
		String path = null;
		StringTokenizer tokens = null;
		int totalTokens = 0;
		
		for(String line : lines) {
			tokens = new StringTokenizer(line, DELIMITER);
			totalTokens = tokens.countTokens();
			
			if(totalTokens != 3 && totalTokens != 4) {
		
				log.debug("Wrong formatted line skipped: " + line);
				
				continue;
			}
			terminology = tokens.nextToken();
			code = tokens.nextToken();
			text = tokens.nextToken();
			if(totalTokens == 4) {
				path = tokens.nextToken();
			} else {
				path = ""; // default for all paths
			}
			addTerm(terminology, code, text, path);
		}
	}
	
	/**
	 * Clears all terms from this termMap
	 * 
	 */
	public void clear() {
		termMap.clear();
	}
 	
	/**
	 * Adds a new term and its text into this termMap
	 * 
	 * @param terminology
	 * @param code
	 * @param text
	 * @param path		
	 */
	public void addTerm(String terminology, String code, String text,
			String path) {
		
		if(log.isDebugEnabled()) {
			log.debug("adding term: " + terminology + DELIMITER + code + 
					DELIMITER + text + DELIMITER + path);
		}
		
		Map> terms = termMap.get(terminology);
		if( terms == null) {
			terms = new TreeMap>();
			termMap.put(terminology, terms);
			
			log.debug("new terminology: " + terminology + " added..");
			
		}
		Map paths = terms.get(code);
		if( paths == null) {
			paths = new TreeMap();
			terms.put(code, paths);
		}
		paths.put(path, text);
	}
	
	/**
	 * Retrieves the text for given terminology and code
	 * 
	 * @param terminology
	 * @param code
	 * @param path 
	 * @return null if not found
	 */
	public String getText(String terminology, String code, String path) {
		Map paths = null;
		String text  = null;
		
		Map> terms = termMap.get(terminology);
		
		if(terms != null) {
			paths = terms.get(code);
			if(paths != null) {
				if(paths.size() == 1 
						&& "".equals(paths.keySet().iterator().next())) {
					text = paths.get("");
				} else {
					text = paths.get(path);
					
					// TODO temp fix if no direct match
					if(text == null) {
						for(Map.Entry entry : paths.entrySet()) {
							if(path.endsWith(entry.getKey())) {
								text = entry.getValue();
							}
						}
					}
				}
			}
		}
		
		log.debug("Retrieved text '" + text + "' for [" + terminology + "::" 
				+ code + "] at path: " + path);
		
		return text;
	}
	
	/**
	 * Retrieves the text for given code_prhase in syntax:
	 * {terminology}::{code}
	 * 
	 * @param codePhrase
	 * @return
	 */
	public String getText(String codePhrase, String path) {
		int i = codePhrase.indexOf(DELIMITER);
		if(i <= 0 || i == codePhrase.length()) {
			throw new IllegalArgumentException(
					"wrong format, expected {terminology}::{code}");
		}
		String terminology = codePhrase.substring(0, i);
		String code = codePhrase.substring(i + 2);
		return getText(terminology, code, path);		
	}
	
	/**
	 * Retrieves the text for given code_prhase
	 * 
	 * @param codePhrase
	 * @return
	 */
	public String getText(CodePhrase codePhrase, String path) {
		return getText(codePhrase.getTerminologyId().toString(), 
				codePhrase.getCodeString(), path);
	}
	
	/**
	 * Counts the total number of terminologies
	 * 
	 * @return 0 if empty
	 */
	public int countTerminologies() {
		return termMap.size();
	}
	
	/**
	 * Gets the internal representation of terms, mainly for testing purpose
	 * 
	 * @return
	 */
	public Map>> getTermMap() {
		return termMap;
	}
	
	/**
	 * Writes this termMap into external file using the following syntax:
	 * {terminology}::{code}::{text} for each line
	 * 
	 * @param filename
	 * @throws IOException
	 */
	public void writeTermMap(String filename) throws IOException {
		StringBuffer buf = new StringBuffer();
		String terminology = null;
		String code = null;
		String text = null;
		String path = null;		
		Map texts = null;
		Map> terms = null;
		
		for(Map.Entry>> entry : termMap.entrySet()) {
			terminology = entry.getKey();
			terms = entry.getValue();
			
			for(Map.Entry> entry2 : terms.entrySet()) {
				
				code = entry2.getKey();
				texts = entry2.getValue();
				
				for(Map.Entry entry3 : texts.entrySet()) {
					
					path = entry3.getKey();
					text = entry3.getValue();
					buf.append(terminology);
					buf.append(DELIMITER);				
					buf.append(code);
					buf.append(DELIMITER);
					buf.append(text);
					buf.append(DELIMITER);
					buf.append(path);
					buf.append("\r\n");
				}
			}
		}
		FileUtils.writeStringToFile(new File(filename), buf.toString(), UTF8);
	}

	private static final String UTF8 = "UTF-8";
	private static final String DELIMITER = "::";
	private static final Logger log = Logger.getLogger(TermMap.class);
	
	// in-memory representation as [terminology, [code, [path, text]]
	private Map>> termMap;  
}
/*
 * ***** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * 
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the 'License'); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an 'AS IS' basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * 
 * The Original Code is TermMap.java
 * 
 * The Initial Developer of the Original Code is Rong Chen. Portions created by
 * the Initial Developer are Copyright (C) 2009-2010 the Initial Developer. All
 * Rights Reserved.
 * 
 * Contributor(s):
 * 
 * Software distributed under the License is distributed on an 'AS IS' basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * 
 * ***** END LICENSE BLOCK *****
 */




© 2015 - 2025 Weber Informatics LLC | Privacy Policy