Greg Sheremeta has uploaded a new change for review. Change subject: userportal, webadmin: use json for documentation mapping files ......................................................................
userportal, webadmin: use json for documentation mapping files Convert from using csv to json for documentation mapping files. Create new JsonServlet to serve the json files to web apps. The servlet is configurable to allow multiple json files (so there can be a common file shared between webadmin and userportal). All configured files are merged into one json String at init time, and cached (to limit server calls). Change-Id: I4d6e8be143583d253943445842c2851fb52274e6 Bug-Url: https://bugzilla.redhat.com/1014859 Signed-off-by: Greg Sheremeta <gsher...@redhat.com> --- M backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml A backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/servlet/JsonServlet.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/DocumentationPathTranslator.java M frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/uicommon/UserPortalConfigurator.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/uicommon/WebAdminConfigurator.java D packaging/manual/DocumentationPath.csv D packaging/manual/UserPortalDocumentationPath.csv A packaging/manual/common.json A packaging/manual/docsconfig.properties A packaging/manual/userportal.json A packaging/manual/webadmin.json 11 files changed, 192 insertions(+), 12 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/92/21392/1 diff --git a/backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml b/backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml index e0dd9f0..c0cd1ac 100644 --- a/backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml +++ b/backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml @@ -56,6 +56,41 @@ <url-pattern>/404.html</url-pattern> </servlet-mapping> + <!-- documentation mapping servlet, 2 instances --> + <servlet> + <servlet-name>WebadminDocsJsonServlet</servlet-name> + <servlet-class>org.ovirt.engine.core.utils.servlet.JsonServlet</servlet-class> + <init-param> + <param-name>configFile</param-name> + <param-value>%{ENGINE_MANUAL}/docsconfig.properties</param-value> + </init-param> + <init-param> + <param-name>configKey</param-name> + <param-value>webadmin</param-value> + </init-param> + </servlet> + <servlet-mapping> + <servlet-name>WebadminDocsJsonServlet</servlet-name> + <url-pattern>/manual/webadmin.json</url-pattern> + </servlet-mapping> + + <servlet> + <servlet-name>UserportalDocsJsonServlet</servlet-name> + <servlet-class>org.ovirt.engine.core.utils.servlet.JsonServlet</servlet-class> + <init-param> + <param-name>configFile</param-name> + <param-value>%{ENGINE_MANUAL}/docsconfig.properties</param-value> + </init-param> + <init-param> + <param-name>configKey</param-name> + <param-value>userportal</param-value> + </init-param> + </servlet> + <servlet-mapping> + <servlet-name>UserportalDocsJsonServlet</servlet-name> + <url-pattern>/manual/userportal.json</url-pattern> + </servlet-mapping> + <!-- Filters --> <!-- Locale Filter, determines the user locale --> <filter> diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/servlet/JsonServlet.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/servlet/JsonServlet.java new file mode 100644 index 0000000..d534eaa --- /dev/null +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/servlet/JsonServlet.java @@ -0,0 +1,127 @@ +package org.ovirt.engine.core.utils.servlet; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ObjectNode; +import org.ovirt.engine.core.utils.EngineLocalConfig; + +/** + * This servlet serves JSON files for easy consumption by GWT. It can merge multiple files + * to limit server requests. + */ +public class JsonServlet extends HttpServlet { + private static final long serialVersionUID = -3938947636590096259L; + private static final Logger log = Logger.getLogger(JsonServlet.class); + + private static final String CONFIG_FILE = "configFile"; //$NON-NLS-1$ + private static final String CONFIG_KEY = "configKey"; //$NON-NLS-1$ + + private static ObjectMapper mapper = new ObjectMapper(); + private String cachedJson = ""; //$NON-NLS-1$ + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + + EngineLocalConfig engineLocalConfig = EngineLocalConfig.getInstance(); + String configFile = ServletUtils.getAsAbsoluteContext( + getServletContext().getContextPath(), + engineLocalConfig.expandString( + config.getInitParameter(CONFIG_FILE).replaceAll("%\\{", "\\${")) //$NON-NLS-1$ //$NON-NLS-2$ + ); + String configKey = config.getInitParameter(CONFIG_KEY); + String[] jsonFiles = new String[0]; + + // which json files are we reading? + File propertiesFile = new File(configFile); + if (propertiesFile.exists() && propertiesFile.canRead()) { + Properties p = new Properties(); + try { + p.load(new FileInputStream(propertiesFile)); + jsonFiles = p.getProperty(configKey, "").trim().split("\\s*,\\s*"); //$NON-NLS-1$ //$NON-NLS-2$ + } + catch (IOException e) { + log.error("problem parsing Properties file: " + propertiesFile.getAbsolutePath(), e); //$NON-NLS-1$ + } + } + + // read the json files + List<JsonNode> nodes = new ArrayList<JsonNode>(); + for (String jsonFile : jsonFiles) { + + File file = new File(configFile.substring(0, configFile.lastIndexOf('/')) + "/" + jsonFile); //$NON-NLS-1$ + if (file.exists() && file.canRead()) { + try { + BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath())); + nodes.add(mapper.readTree(reader)); + } + catch (IOException e) { + log.error("problem parsing documentation mapping file: " + file.getAbsolutePath(), e); //$NON-NLS-1$ + } + } + } + + // merge the json files + if (nodes.size() > 0) { + JsonNode destination = nodes.get(0); + for (int i = 1; i < nodes.size(); i++) { + destination = merge(destination, nodes.get(i)); + } + + this.cachedJson = destination.toString(); + } + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + if (cachedJson != null) { + response.setContentType("application/json"); //$NON-NLS-1$ + PrintStream printStream = new PrintStream(response.getOutputStream()); + printStream.print(cachedJson); + } + else { + response.sendError(500); + } + } + + protected static JsonNode merge(JsonNode destination, JsonNode source) { + + Iterator<String> fieldNames = source.getFieldNames(); + while (fieldNames.hasNext()) { + + String fieldName = fieldNames.next(); + JsonNode jsonNode = destination.get(fieldName); + // if field doesn't exist or is an embedded object + if (jsonNode != null && jsonNode.isObject()) { + merge(jsonNode, source.get(fieldName)); + } + else { + if (destination instanceof ObjectNode) { + // Overwrite field + JsonNode value = source.get(fieldName); + ((ObjectNode) destination).put(fieldName, value); + } + } + } + + return destination; + } +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/DocumentationPathTranslator.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/DocumentationPathTranslator.java index cb0e958..1a3d46d 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/DocumentationPathTranslator.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/DocumentationPathTranslator.java @@ -3,8 +3,19 @@ import java.util.HashMap; import java.util.Map; +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsonUtils; +import com.google.gwt.json.client.JSONObject; +import com.google.gwt.json.client.JSONString; +import com.google.gwt.json.client.JSONValue; + public class DocumentationPathTranslator { private static Map<String, String> documentationPathMap; + + // GWT overlay for the JSON object containing the help mappings + private static class Mapping extends JavaScriptObject { + protected Mapping() {} + } public static String getPath(String hashName) { @@ -19,18 +30,18 @@ public static void init(String fileContent) { + // fileContent is a JSON object with all unknown fields + Mapping mapping = JsonUtils.safeEval(fileContent); + JSONObject mappingJson = new JSONObject(mapping); + documentationPathMap = new HashMap<String, String>(); - String[] lines = fileContent.split("\n"); //$NON-NLS-1$ - for (String line : lines) { - String[] parts = line.split(","); //$NON-NLS-1$ - - if (parts.length > 1) { - String name = parts[0] != null && !parts[0].isEmpty() ? parts[0] : null; - String path = parts[1] != null && !parts[1].isEmpty() ? parts[1] : null; - if (name != null && path != null && !documentationPathMap.containsKey(name)) { - documentationPathMap.put(name, path); - } + for (String docTag : mappingJson.keySet()) { + JSONValue url = mappingJson.get(docTag); + JSONString urlString = url.isString(); + if (docTag != null && urlString != null && !docTag.isEmpty() && + !urlString.stringValue().isEmpty() && !documentationPathMap.containsKey(docTag)) { + documentationPathMap.put(docTag, urlString.stringValue()); } } } diff --git a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/uicommon/UserPortalConfigurator.java b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/uicommon/UserPortalConfigurator.java index b8c333e..043052a 100644 --- a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/uicommon/UserPortalConfigurator.java +++ b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/uicommon/UserPortalConfigurator.java @@ -153,7 +153,7 @@ } protected void fetchDocumentationFile() { - fetchFile(getDocumentationBaseURL() + "UserPortalDocumentationPath.csv", documentationFileFetchedEvent); //$NON-NLS-1$ + fetchFile(getDocumentationBaseURL() + "userportal.json", documentationFileFetchedEvent); //$NON-NLS-1$ } } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/uicommon/WebAdminConfigurator.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/uicommon/WebAdminConfigurator.java index 25890e5..137ae57 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/uicommon/WebAdminConfigurator.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/uicommon/WebAdminConfigurator.java @@ -100,7 +100,7 @@ } protected void fetchDocumentationFile() { - fetchFile(getDocumentationBaseURL() + "DocumentationPath.csv", documentationFileFetchedEvent); //$NON-NLS-1$ + fetchFile(getDocumentationBaseURL() + "webadmin.json", documentationFileFetchedEvent); //$NON-NLS-1$ } } diff --git a/packaging/manual/DocumentationPath.csv b/packaging/manual/DocumentationPath.csv deleted file mode 100644 index e69de29..0000000 --- a/packaging/manual/DocumentationPath.csv +++ /dev/null diff --git a/packaging/manual/UserPortalDocumentationPath.csv b/packaging/manual/UserPortalDocumentationPath.csv deleted file mode 100644 index e69de29..0000000 --- a/packaging/manual/UserPortalDocumentationPath.csv +++ /dev/null diff --git a/packaging/manual/common.json b/packaging/manual/common.json new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/packaging/manual/common.json @@ -0,0 +1 @@ + diff --git a/packaging/manual/docsconfig.properties b/packaging/manual/docsconfig.properties new file mode 100644 index 0000000..334822f --- /dev/null +++ b/packaging/manual/docsconfig.properties @@ -0,0 +1,4 @@ +# lists of json files that contain documentation mappings for webadmin and userportal +webadmin=common.json,webadmin.json +userportal=common.json,userportal.json + diff --git a/packaging/manual/userportal.json b/packaging/manual/userportal.json new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/packaging/manual/userportal.json @@ -0,0 +1 @@ + diff --git a/packaging/manual/webadmin.json b/packaging/manual/webadmin.json new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/packaging/manual/webadmin.json @@ -0,0 +1 @@ + -- To view, visit http://gerrit.ovirt.org/21392 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4d6e8be143583d253943445842c2851fb52274e6 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Greg Sheremeta <gsher...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches