package org.ovirt.engine.ui.common.uicommon; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsonUtils; import com.google.gwt.i18n.client.LocaleInfo; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONString; /** * Responsible for translating helpTag mappings into context-sensitive help URLs. * * This class is initialized with a String of json that is read from the server. * That json contains helptag-URL mappings for every locale that has the * documentation package installed. * * It parses that json and caches csh mappings for the session. We first try to * find csh for the user's locale. If that's not found, we fall back to English. * * @see ContextSensitiveHelpMappingServlet for the server-side portion of this operation, * where the json is generated. */ public class ContextSensitiveHelpManager { private static final Logger logger = Logger.getLogger(ContextSensitiveHelpManager.class.getName()); private static final String currentLocale = LocaleInfo.getCurrentLocale().getLocaleName().replaceAll("_", "-"); //$NON-NLS-1$ //$NON-NLS-2$ private static final String ENGLISH = "en-US"; //$NON-NLS-1$ private static Map<String, String> cshMappings = null; // GWT overlay for the JSON object private static class Mapping extends JavaScriptObject { @SuppressWarnings("unused") protected Mapping() {} // required for GWT } /** * Get the csh path for a helpTag. Called by models / dialogs to see if this dialog has help available. * * @return URL to csh, or null if this dialog has no csh available. */ public static String getPath(String helpTag) { if (cshMappings == null || cshMappings.isEmpty()) { // no documentation is installed return null; } if (helpTag != null) { return cshMappings.get(helpTag); } return null; } /** * Get json mappings for the user's current locale, or fall back to English * if user's locale is not installed. * * fileContent is a JSON object with this structure: * * { * 'en-US' : { * 'someHelpTag' : '/some/url.html' * }, * 'ja-JP' : { * 'someHelpTag2' : '/some/url2.html' * }, * etc. * } */ public static void init(String fileContent) { Mapping jsonEval = JsonUtils.safeEval(fileContent); JSONObject json = new JSONObject(jsonEval); Map<String, Map<String, String>> detectedMappings = parseJson(json); // all locale's mappings are now in detectedMappings. only need to save the user's locale's mappings, or English. if (detectedMappings.isEmpty()) { logger.info("No context-sensitive help was found on the server. It will not be available for this session."); //$NON-NLS-1$ return; } logger.info("Context-sensitive help is installed on the server. The following locales are available: " //$NON-NLS-1$ + detectedMappings.keySet()); if (detectedMappings.keySet().contains(currentLocale)) { logger.info("Context-sensitive help for your locale, " + currentLocale + ", is installed and loaded."); //$NON-NLS-1$ //$NON-NLS-2$ cshMappings = detectedMappings.get(currentLocale); } else if (!currentLocale.equals(ENGLISH) && detectedMappings.keySet().contains(ENGLISH)) { logger.info("Context-sensitive help wasn't found for your locale, " + currentLocale + ". Using English as a fallback."); //$NON-NLS-1$ //$NON-NLS-2$ cshMappings = detectedMappings.get(ENGLISH); } else { logger.info("Context-sensitive help wasn't found for your locale, " + currentLocale + ", or the fallback locale, English. " //$NON-NLS-1$ //$NON-NLS-2$ + "Context-sensitive help will not be available for this session."); //$NON-NLS-1$ cshMappings = null; } } protected static Map<String, Map<String, String>> parseJson(JSONObject json) { Map<String, Map<String, String>> detectedMappings = new HashMap<>(); for (String locale : json.keySet()) { JSONObject localeObject = json.get(locale).isObject(); HashMap<String, String> localeMappings = new HashMap<>(); for (String docTag : localeObject.keySet()) { JSONString urlString = localeObject.get(docTag).isString(); if (urlString != null && !docTag.isEmpty() && !urlString.stringValue().isEmpty() && !localeMappings.containsKey(docTag)) { localeMappings.put(docTag, urlString.stringValue()); } } // only add the locale to the Map if there were mappings. // i.e. a locale with no mappings is treated as if it didn't exist. if (!localeMappings.isEmpty()) { detectedMappings.put(locale, localeMappings); } } return detectedMappings; } }