Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Creative commons Attribution-NonCommercial license. http://creativecommons.org/licenses/by-nc/2.5/au/deed.en_GB NO WARRANTY IS GIVEN OR IMPLIED, USE AT YOUR OWN RISK.
  
  package base.text;
  
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
Cache all available translations of text strings discovered within the application. Each newly discovered string may be persisted to the database. Each string persisted in the database may have a corresponding translation in any language. Initialise on web application startup as follows:

 LocalText.instance(dataSource);
 
At run time, text strings are looked up using the static helper function:

 LocalText.local("Sample text", locale);
 
Request that any recently newly discovered text is persisted back into the database:

 LocalText.instance().persistNewTextForTranslation();
 
Translation helper functions
The following methods are used to view and update text translations.

Search for a particular keyword in any string in any language:

 List<String> items = LocalText.instance().search("keyword");
 
Search for a particular keyword in any string in a pre-defined language, or null for the default text:

 List<String> items = LocalText.instance().search("en", "keyword");
 
Update the application with a new translation of a particular text string:

 LocalText.instance().translate(hash, "en", "This is the english version of the string");
 
 
 public class LocalText {
 
 	private static LocalText instance;
 
 	public static LocalText instance(DataSource dsthrows IOException {
 		if( == null) {
 			 = new LocalText(ds);
 		}
 		return ;
 	}
 
 	public static String local(String textString language) {
 		if( == null) {
 			throw new IllegalStateException("LocalText.instance() must be called before LocalText.local()");
 		}
 		return .getTranslation(textlanguage);
 	}
 
 	public static String local(String textLocale locale) {
 		if( == null) {
 			throw new IllegalStateException("LocalText.instance() must be called before LocalText.local()");
 		}
 		return .getTranslation(textlocale.getLanguage() +"_" + locale.getCountry());
 	}
 
 	private Map<IntegerStringdefaults = new Hashtable<IntegerString>();
 	private Map<StringMap<IntegerString>> strings = new Hashtable<StringMap<IntegerString>>();
 	private Set<StringdatabaseInsertQueue = new HashSet<String>();
 	private DataSource ds;

Instantiate an instance of a LocalText cache, backed by a JDBC data source.

Parameters:
ds
Throws:
java.io.IOException
	public LocalText(DataSource dsthrows IOException {
		this. = ds;
	}

If a translation exists for the `text` parameter, return the translation, otherwise return the `text` parameter itself.

Parameters:
text Default text to display to the end user.
language Language to check for translated version of the text.
Returns:
Returns the `text` input parameter unless a translation exists.
	public String getTranslation(String textString language) {
		String result = null;
		Integer hash = text.hashCode();
		if(.containsKey(language)) {
			result = .get(language).get(hash);
		}
		if(result == null) {
			result = text;
			if(!.containsKey(hash)) {
				.put(hashtext);
			}
		}
		return result;
	}
	public String getTranslation(String textLocale locale) {
		return local(textlocale.getLanguage() +"_" + locale.getCountry());
	}

Should be called on a regular scheduled interval by the web application, to ensure any as yet untranslated text is added to the list of text strings.

	public void persistNewTextForTranslation() throws IOException {
		Connection c = null;
		PreparedStatement p1 = null;
		PreparedStatement p2 = null;
		ResultSet r = null;
		Set<Stringuncommitted = new HashSet<String>();
		try {
			p2 = c.prepareStatement("select t_hash from translations where t_hash=? and t_lang='default'");
			p1 = c.prepareStatement("insert into translations (t_hash,t_text,t_lang) values(?,?,'default')");
			uncommitted.addAll(items);
			for(String text : items) {
				p2.setInt(1, text.hashCode());
				r = p2.executeQuery();
				if(!r.next()) {
					p1.setInt(1, text.hashCode());
					p1.setString(2, text);
					p1.execute();
					uncommitted.remove(text);
				}
				r.close();
				r = null;
			}
catch(SQLException e) {
			throw new IOException(e);
finally {
			if(r != null) { try { r.close(); } catch(SQLException e) {} }
			if(p1 != null) { try { p1.close(); } catch(SQLException e) {} }
			if(p2 != null) { try { p2.close(); } catch(SQLException e) {} }
			if(c != null) { try { c.close(); } catch(SQLException e) {} }
			// If some sort of error results in saved text not being persisted, put
			// it back on the queue for later.
			for(String item : uncommitted) {
			}
		}
	}
	public void translate(int hashString languageString newTextthrows SQLException {
		if(language == null || language.equalsIgnoreCase("default")) {
			throw new IllegalArgumentException("May not directly define default text at this time.");
		}
		Connection c = null;
		PreparedStatement p1 = null;
		PreparedStatement p2 = null;
		PreparedStatement p3 = null;
		ResultSet r = null;
		try {
			p3 = c.prepareStatement("select t_hash from translations where t_hash=? and t_lang='default'");
			p3.setInt(1, hash);
			r = p3.executeQuery();
			boolean hasDefault = true;
			if(!r.next()) {
				hasDefault = false;
			}
			r.close();
			r = null;
			p3.close();
			p3 = null;
			if(!hasDefault) {
				throw new IllegalArgumentException("Attempting to define a translation for a hash with no default text string.");
			}
			p2 = c.prepareStatement("select t_hash from translations where t_hash=? and t_lang=?");
			p2.setInt(1, hash);
			p2.setString(2, language);
			r = p2.executeQuery();
			if(!r.next()) {
				if(newText != null) {
					p1 = c.prepareStatement("insert into translations (t_hash,t_text,t_lang) values(?,?,?)");
					p1.setInt(1, hash);
					p1.setString(2, newText);
					p1.setString(3, language);
					p1.execute();
				}
else {
				if(newText == null) {
					p1 = c.prepareStatement("delete from translations where t_hash=? and t_lang=?");
					p1.setInt(1, hash);
					p1.setString(2, language);
					p1.execute();
else {
					p1 = c.prepareStatement("update translations set t_text=? where t_hash=? and t_lang=?");
					p1.setString(1, newText);
					p1.setInt(2, hash);
					p1.setString(3, language);
					p1.execute();
				}
			}
			r.close();
			r = null;
finally {
			if(r != null) { r.close(); }
			if(p1 != null) { p1.close(); }
			if(p2 != null) { p2.close(); }
			if(p3 != null) { p3.close(); }
			if(c != null) { c.close(); }
		}
		if(!.containsKey(language)) {
			.put(languagenew Hashtable<IntegerString>());
		}
		if(newText != null) {
			.get(language).put(hashnewText);
else {
			.get(language).remove(hash);
		}
	}

Called on web application startup to trigger loading all available translations from the database.

	private void loadTranslationsFromDatabase() throws IOException {
		Connection c = null;
		PreparedStatement p = null;
		ResultSet r = null;
		try {
			p = c.prepareStatement("select t_hash, t_text, t_lang from translations");
			r = p.executeQuery();
			while(r.next()) {
				int hash = r.getInt(1);
				String text = r.getString(2);
				String language = r.getString(3);
				if(text == null) {
					continue;
				}
				if(language.equalsIgnoreCase("default")) {
					.put(hashtext);
else {
					if(!.containsKey(language)) {
						.put(languagenew Hashtable<IntegerString>());
					}
					.get(language).put(hashtext);
				}
			}
			r.close();
			r = null;
catch(SQLException e) {
			throw new IOException(e);
finally {
			if(r != null) { try { r.close(); } catch(SQLException e) {} }
			if(p != null) { try { p.close(); } catch(SQLException e) {} }
			if(c != null) { try { c.close(); } catch(SQLException e) {} }
		}
	}

	public List<LocalTranslationsearch(String keywordthrows IOException {
		Connection c = null;
		PreparedStatement p = null;
		ResultSet r = null;
		try {
			p = c.prepareStatement("select t_hash, t_text, t_lang from translations where t_text like lower(?) order by t_hash");
			if(keyword == null || keyword.length() == 0 || keyword.equals("%") || keyword.equals("*")) {
				keyword = "%";
else {
				if(!keyword.contains("%")) {
					keyword = "%" + keyword.toLowerCase() + "%";
else {
					keyword = keyword.toLowerCase();
				}
			}
			p.setString(1, keyword);
			r = p.executeQuery();
			while(r.next()) {
				results.add(new LocalTranslation(r.getInt(1), r.getString(3), r.getString(2)));
			}
catch(SQLException e) {
			throw new IOException(e);
finally {
			if(r != null) { try { r.close(); } catch(SQLException e) {} }
			if(p != null) { try { p.close(); } catch(SQLException e) {} }
			if(c != null) { try { c.close(); } catch(SQLException e) {} }
		}
		return results;
	}

		Connection c = null;
		PreparedStatement p = null;
		ResultSet r = null;
		try {
					"select t_hash, t_text, t_lang from translations where t_lang='default' " +
					"union " +
					"select t_hash, t_text, t_lang from translations where t_lang!='default' "
					);
			r = p.executeQuery();
			while(r.next()) {
				if(r.getString(3).equals("default")) {
					results.put(r.getInt(1), new LocalTranslationSet(r.getInt(1), r.getString(2)));
else {
					LocalTranslationSet i = results.get(r.getInt(1));
					if(i == null) {
						..println("Missing default text for string: " + r.getString(2) + ":" + r.getString(3));
else {
						i.addText(r.getString(3), r.getString(2));
					}
				}
			}
catch(SQLException e) {
			throw new IOException(e);
finally {
			if(r != null) { try { r.close(); } catch(SQLException e) {} }
			if(p != null) { try { p.close(); } catch(SQLException e) {} }
			if(c != null) { try { c.close(); } catch(SQLException e) {} }
		}
		return results.values();
	}

	public List<LocalTranslationsearch(int hashthrows IOException {
		Connection c = null;
		PreparedStatement p = null;
		ResultSet r = null;
		try {
			p = c.prepareStatement("select t_hash, t_text, t_lang from translations where t_hash=? order by t_lang");
			p.setInt(1, hash);
			r = p.executeQuery();
			while(r.next()) {
				results.add(new LocalTranslation(r.getInt(1), r.getString(3), r.getString(2)));
			}
catch(SQLException e) {
			throw new IOException(e);
finally {
			if(r != null) { try { r.close(); } catch(SQLException e) {} }
			if(p != null) { try { p.close(); } catch(SQLException e) {} }
			if(c != null) { try { c.close(); } catch(SQLException e) {} }
		}
		return results;
	}

Wipe all information about translations from memory and from the database. Used by the test cases to reset test data.

	public void wipe() throws SQLException {
		Connection c = null;
		PreparedStatement p = null;
		try {
			p = c.prepareStatement("delete from translations");
			 = new Hashtable<>();
			 = new Hashtable<>();
finally {
			if(p != null) { p.close(); }
			if(c != null) { c.close(); }
		}
	}

Add new strings that require translation.

Parameters:
text
	private synchronized void registerNewTextForTranslation(String text) {
	}

Retrieve the list of recently discovered strings that require translation.

Returns:
List of recently discovered strings that need translation.
	private synchronized Set<StringnewTextForTranslation() {
		return items;
	}

Create the translations database table. Rather than trying to guess which database type we are talking to, just issue create statements for both MySQL and/or Oracle to see which one sticks.

Parameters:
c
	private void createTable(Connection c) {
		PreparedStatement s = null;
		try {
					"create table translations (" +
					"	t_hash integer, "+
					"	t_lang nvarchar2(32), " +
					"	t_text nvarchar2(254), " +
					"	CONSTRAINT translations_pk PRIMARY KEY (t_hash,t_lang)) ");
catch(SQLException e) {
			// Fails if table already exists, or this is not Oracle.
finally {
			if(s != null) { try { s.close(); s = null; } catch(Exception f){} }
		}
		try {
					"create table if not exists translations (" +
					"	t_hash integer, " +
					"	t_lang varchar(32), "+
					"	t_text varchar(254), "+
					"	PRIMARY KEY(t_hash,t_lang)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
catch(SQLException e) {
			// Fails if this is not MySQL
finally {
			if(s != null) { try { s.close(); } catch(Exception f){} }
		}
	}
New to GrepCode? Check out our FAQ X