/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.enonic.esl.xml.XMLTool; import com.enonic.vertical.adminweb.VerticalAdminLogger; @Service public class AdminConsoleTranslationService implements InitializingBean { /** * Language map singleton. */ private static AdminConsoleTranslationService languageMap; /** * Internal map. */ private Map<String, Map<String, String>> internalMap; /** * Default translation map */ private Map<String, String> defaultTranslationMap; /** * Default language * */ private String defaultLanguageCode; public static AdminConsoleTranslationService getInstance() { return languageMap; } public AdminConsoleTranslationService() { languageMap = this; } @Value("${cms.admin.defaultLanguage}") public void setDefaultLanguageCode( String value ) { this.defaultLanguageCode = value; } @Override public void afterPropertiesSet() throws Exception { init(); } protected void init() { // the internal language map to build Map<String, Map<String, String>> languageMap = new HashMap<String, Map<String, String>>(); BufferedReader in = null; try { // langfile.csv contains the language configuration in = new BufferedReader( new InputStreamReader( getClass().getResourceAsStream( "langfile.csv" ), "UTF-8" ) ); ArrayList<Map<String, String>> translationMapList = new ArrayList<Map<String, String>>(); String line = in.readLine(); StringTokenizer st = new StringTokenizer( line, "|" ); String variable = st.nextToken(); // the first line will always contain the %languageCode% variable and // this code section initializes the map for each language while ( st.hasMoreTokens() ) { String languageCode = st.nextToken(); Map<String, String> translationMap = new HashMap<String, String>(); translationMap.put( variable, languageCode ); languageMap.put( languageCode, translationMap ); translationMapList.add( translationMap ); } // read each variable one by one with translations for each language line = in.readLine(); while ( line != null && line.length() > 0 ) { st = new StringTokenizer( line, "|" ); variable = st.nextToken(); for ( int i = 0; st.hasMoreTokens(); i++ ) { String value = st.nextToken(); try { translationMapList.get( i ).put( variable, value ); } catch ( IndexOutOfBoundsException e ) { throw new IllegalStateException( "Error parsing line: " + line ); } } line = in.readLine(); } // close the langfile.csv stream in.close(); in = null; // the language map are only available for read-only access, so each translationMap // are made read-only as well as the internal language map itself for ( Iterator<Map.Entry<String, Map<String, String>>> iter = languageMap.entrySet().iterator(); iter.hasNext(); ) { Map.Entry<String, Map<String, String>> entry = iter.next(); entry.setValue( Collections.unmodifiableMap( entry.getValue() ) ); } this.internalMap = Collections.unmodifiableMap( languageMap ); this.defaultTranslationMap = languageMap.get( defaultLanguageCode ); } catch ( IOException ioe ) { String msg = "Failed to read language file: %t"; VerticalAdminLogger.errorAdmin( msg, ioe ); } finally { try { if ( in != null ) { in.close(); } } catch ( IOException ioe ) { String msg = "Failed to close language file: %t"; VerticalAdminLogger.warn( msg, ioe ); } } } /** * @param languageCode * @return */ public Map<String, String> getTranslationMap( String languageCode ) { if ( languageCode == null ) { return defaultTranslationMap; } else { if ( !internalMap.containsKey( languageCode ) ) { throw new IllegalArgumentException( "Unknown language code: " + languageCode ); } return internalMap.get( languageCode ); } } public String getTranslation( final String key, final String languageCode ) { Map<String, String> translationMap = getTranslationMap( languageCode ); return translationMap.get( key ); } /** * Get the default language code. * * @return */ public String getDefaultLanguageCode() { return defaultLanguageCode; } public void toDoc( Document doc, String languageCode ) { Element languagesElem = XMLTool.createElement( doc, doc.getDocumentElement(), "languages" ); for ( Iterator<String> iter = internalMap.keySet().iterator(); iter.hasNext(); ) { String code = iter.next(); Element languageElem = XMLTool.createElement( doc, languagesElem, "language" ); languageElem.setAttribute( "code", code ); Map<String, String> translationMap = getTranslationMap( languageCode ); String description = translationMap.get( "%lang" + code.toUpperCase() + "%" ); languageElem.setAttribute( "description", description ); } } public void toDoc( org.jdom.Document doc, String languageCode ) { org.jdom.Element rootElem = doc.getRootElement(); org.jdom.Element languagesElem = new org.jdom.Element( "languages" ); rootElem.addContent( languagesElem ); for ( Iterator<String> iter = internalMap.keySet().iterator(); iter.hasNext(); ) { String code = iter.next(); org.jdom.Element languageElem = new org.jdom.Element( "language" ); languagesElem.addContent( languageElem ); languageElem.setAttribute( "code", code ); Map<String, String> translationMap = getTranslationMap( languageCode ); String description = translationMap.get( "%lang" + code.toUpperCase() + "%" ); languageElem.setAttribute( "description", description ); } } }