Bug 1457749: Part 2 - Update UpdateRDFConverter to use RDFDataSource.jsm. r?Mossop draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 28 Apr 2018 19:20:38 -0700
changeset 789550 ff2559cef77d7918f5bfc3053a6604ad716ef15a
parent 789549 4ce74cb7e1e2ab85ce0bfaa9c1242289ac85f239
child 789551 86b6a154923b7f6c2d5efa8e57593ddcf94f1750
push id108277
push usermaglione.k@gmail.com
push dateSun, 29 Apr 2018 03:22:58 +0000
reviewersMossop
bugs1457749
milestone61.0a1
Bug 1457749: Part 2 - Update UpdateRDFConverter to use RDFDataSource.jsm. r?Mossop MozReview-Commit-ID: HbJ3vBSBXH2
toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm
--- a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm
+++ b/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm
@@ -1,159 +1,142 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 var EXPORTED_SYMBOLS = ["UpdateRDFConverter"];
 
-const PREFIX_NS_EM          = "http://www.mozilla.org/2004/em-rdf#";
+ChromeUtils.defineModuleGetter(this, "RDFDataSource",
+                               "resource://gre/modules/addons/RDFDataSource.jsm");
+ChromeUtils.defineModuleGetter(this, "Services",
+                               "resource://gre/modules/Services.jsm");
+
 const PREFIX_ITEM           = "urn:mozilla:item:";
 const PREFIX_EXTENSION      = "urn:mozilla:extension:";
 const PREFIX_THEME          = "urn:mozilla:theme:";
 
 const TOOLKIT_ID            = "toolkit@mozilla.org";
 
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+function EM_R(aProperty) {
+  return `http://www.mozilla.org/2004/em-rdf#${aProperty}`;
+}
 
-XPCOMUtils.defineLazyServiceGetters(this, {
-  gRDF: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"],
-  containerUtils: ["@mozilla.org/rdf/container-utils;1", "nsIRDFContainerUtils"],
-});
+function getValue(literal) {
+  return literal && literal.getValue();
+}
+
+function getProperty(resource, property) {
+  return getValue(resource.getProperty(EM_R(property)));
+}
 
-const RDFContainer = Components.Constructor(
-  "@mozilla.org/rdf/container;1", "nsIRDFContainer", "Init");
-const RDFDataSource = Components.Constructor(
-  "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", "nsIRDFDataSource");
-const RDFParser = Components.Constructor(
-  "@mozilla.org/rdf/xml-parser;1", "nsIRDFXMLParser");
+function getBoolProperty(resource, property) {
+  return getValue(resource.getProperty(EM_R(property))) == "true";
+}
 
-/**
- * Parses an RDF style update manifest into a JSON-style update
- * manifest.
- *
- * @param {XMLHttpRequest> aRequest
- *         The XMLHttpRequest that has retrieved the update manifest
- * @returns {object} a JSON update manifest.
- */
-function parseRDFManifest(aRequest) {
-  function EM_R(aProp) {
-    return gRDF.GetResource(PREFIX_NS_EM + aProp);
+class Manifest {
+  constructor(ds) {
+    this.ds = ds;
+  }
+
+  static loadFromString(text) {
+    return new this(RDFDataSource.loadFromString(text));
+  }
+
+  static loadFromBuffer(buffer) {
+    return new this(RDFDataSource.loadFromBuffer(buffer));
   }
 
-  function getValue(aLiteral) {
-    if (aLiteral instanceof Ci.nsIRDFLiteral)
-      return aLiteral.Value;
-    if (aLiteral instanceof Ci.nsIRDFResource)
-      return aLiteral.Value;
-    if (aLiteral instanceof Ci.nsIRDFInt)
-      return aLiteral.Value;
-    return null;
-  }
-
-  function getProperty(aDs, aSource, aProperty) {
-    return getValue(aDs.GetTarget(aSource, EM_R(aProperty), true));
-  }
-
-  function getBooleanProperty(aDs, aSource, aProperty) {
-    let propValue = aDs.GetTarget(aSource, EM_R(aProperty), true);
-    if (!propValue)
-      return undefined;
-    return getValue(propValue) == "true";
+  static async loadFromFile(uri) {
+    return new this(await RDFDataSource.loadFromFile(uri));
   }
+}
 
-  let rdfParser = new RDFParser();
-  let ds = new RDFDataSource();
-  rdfParser.parseString(ds, aRequest.channel.URI, aRequest.responseText);
+class UpdateRDF extends Manifest {
+  decode() {
+    let addons = {};
+    let result = {addons};
 
-  let addons = {};
-  let result = {addons};
+    for (let resource of this.ds.getAllResources()) {
+      let id;
+      let uri = resource.getURI();
+      for (let prefix of [PREFIX_EXTENSION, PREFIX_THEME, PREFIX_ITEM]) {
+        if (uri.startsWith(prefix)) {
+          id = uri.substr(prefix.length);
+          break;
+        }
+      }
+      if (!id) {
+        continue;
+      }
+
+      let addon = {};
+      addons[id] = addon;
+
+      let updatesProp = resource.getProperty(EM_R("updates"));
+      if (!updatesProp || !updatesProp.getChildren) {
+        continue;
+      }
+
+      let updates = [];
+      addon.updates = updates;
+
+      for (let item of updatesProp.getChildren()) {
+        let version = getProperty(item, "version");
+
+        for (let targetApp of item.getObjects(EM_R("targetApplication"))) {
+          let appEntry = {};
 
-  for (let addonRes of XPCOMUtils.IterSimpleEnumerator(ds.GetAllResources(), Ci.nsIRDFResource)) {
-    let value = addonRes.ValueUTF8;
-    let id;
-    for (let prefix of [PREFIX_EXTENSION, PREFIX_THEME, PREFIX_ITEM]) {
-      if (value.startsWith(prefix)) {
-        id = value.substr(prefix.length);
-        break;
+          let minVersion = getProperty(targetApp, "minVersion");
+          if (minVersion) {
+            appEntry.strict_min_version = minVersion;
+          }
+
+          let maxVersion = getProperty(targetApp, "maxVersion");
+          if (maxVersion) {
+            if (getBoolProperty(targetApp, "strictCompatibility")) {
+              appEntry.strict_max_version = maxVersion;
+            } else {
+              appEntry.advisory_max_version = maxVersion;
+            }
+          }
+
+          let appId = getProperty(targetApp, "id");
+          if (!appId) {
+            continue;
+          }
+          if (appId === TOOLKIT_ID || appId === Services.appinfo.ID) {
+            appId = "gecko";
+          }
+
+          let update = {
+            applications: {[appId]: appEntry},
+          };
+          if (version) {
+            update.version = version;
+          }
+          let updateLink = getProperty(targetApp, "updateLink");
+          if (updateLink) {
+            update.update_link = updateLink;
+          }
+          let updateInfoURL = getProperty(targetApp, "updateInfoURL");
+          if (updateInfoURL) {
+            update.update_info_url = updateInfoURL;
+          }
+          let updateHash = getProperty(targetApp, "updateHash");
+          if (updateHash) {
+            update.update_hash = updateHash;
+          }
+
+          updates.push(update);
+        }
       }
     }
-    if (!id) {
-      continue;
-    }
 
-    let addon = {};
-    addons[id] = addon;
-
-    let updatesTarget = ds.GetTarget(addonRes, EM_R("updates"), true);
-    if (!(updatesTarget instanceof Ci.nsIRDFResource) ||
-        !containerUtils.IsContainer(ds, updatesTarget)) {
-      continue;
-    }
-
-    let updates = [];
-    addon.updates = updates;
-
-    let ctr = new RDFContainer(ds, updatesTarget);
-    for (let item of XPCOMUtils.IterSimpleEnumerator(ctr.GetElements(),
-                                                     Ci.nsIRDFResource)) {
-      let version = getProperty(ds, item, "version");
-
-      let targetApps = ds.GetTargets(item, EM_R("targetApplication"), true);
-      for (let targetApp of XPCOMUtils.IterSimpleEnumerator(targetApps,
-                                                            Ci.nsIRDFResource)) {
-        let appEntry = {};
-
-        let minVersion = getProperty(ds, targetApp, "minVersion");
-        if (minVersion) {
-          appEntry.strict_min_version = minVersion;
-        }
-
-        let maxVersion = getProperty(ds, targetApp, "maxVersion");
-        if (maxVersion) {
-          if (getBooleanProperty(ds, targetApp, "strictCompatibility")) {
-            appEntry.strict_max_version = maxVersion;
-          } else {
-            appEntry.advisory_max_version = maxVersion;
-          }
-        }
-
-        let appId = getProperty(ds, targetApp, "id");
-        if (!appId) {
-          continue;
-        }
-        if (appId === TOOLKIT_ID || appId === Services.appinfo.ID) {
-          appId = "gecko";
-        }
-
-        let update = {
-          applications: {[appId]: appEntry},
-        };
-        if (version) {
-          update.version = version;
-        }
-        let updateLink = getProperty(ds, targetApp, "updateLink");
-        if (updateLink) {
-          update.update_link = updateLink;
-        }
-        let updateInfoURL = getProperty(ds, targetApp, "updateInfoURL");
-        if (updateInfoURL) {
-          update.update_info_url = updateInfoURL;
-        }
-        let updateHash = getProperty(ds, targetApp, "updateHash");
-        if (updateHash) {
-          update.update_hash = updateHash;
-        }
-
-        updates.push(update);
-      }
-    }
+    return result;
   }
-
-  return result;
 }
 
 var UpdateRDFConverter = {
   convertToJSON(request) {
-    return parseRDFManifest(request);
+    return UpdateRDF.loadFromString(request.responseText).decode();
   },
 };