code: public Map<String, String> readLanguage(String appid, String langCode) {
  		if (StringUtils.isBlank(langCode) || langCode.equals(getDefaultLanguageCode())) {
  			return getDefaultLanguage(appid);
  		} else if (langCode.length() > 2 && !ALL_LOCALES.containsKey(langCode)) {
  			return readLanguage(appid, langCode.substring(0, 2));
  		} else if (LANG_CACHE.containsKey(langCode)) {
  			return LANG_CACHE.get(langCode);
  		}
  
  		// load language map from file
  		Map<String, String> lang = readLanguageFromFile(appid, langCode);
  		if (lang == null || lang.isEmpty()) {
  			// or try to load from DB
  			lang = new TreeMap<String, String>(getDefaultLanguage(appid));
  			Sysprop s = dao.read(appid, keyPrefix.concat(langCode));
  			if (s != null && !s.getProperties().isEmpty()) {
  				Map<String, Object> loaded = s.getProperties();
  				for (Map.Entry<String, String> entry : lang.entrySet()) {
  					if (loaded.containsKey(entry.getKey())) {
  						lang.put(entry.getKey(), String.valueOf(loaded.get(entry.getKey())));
  					} else {
  						lang.put(entry.getKey(), entry.getValue());
  					}
  				}
  			}
  			LANG_CACHE.put(langCode, lang);
  		}
  		return Collections.unmodifiableMap(lang);
  	}
docs: Returns a map of all translations for a given language.
  Defaults to the default language which must be set.
  @param appid appid name of the {@link com.erudika.para.core.App}
  @param langCode the 2-letter language code
  @return the language map