Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
CB-5237 Implemented config-file support in config.xml to inject custo…
…m xml into the bar-descriptor.xml

Reviewed by Bryan Higgins <bhiggins@blackberry.com>
Tested by Jenny Gee <jgee@blackberry.com>
  • Loading branch information
jkeshavarzi authored and bryanhiggins committed Nov 1, 2013
1 parent 8f3c360 commit 1639fc17f72d11cfac11ebac1d3e500440f6bfcf
Showing 3 changed files with 203 additions and 2 deletions.
@@ -25,6 +25,8 @@ var fs = require("fs"),
fileManager = require("./file-manager"),
utils = require("./packager-utils"),
i18nMgr = require("./i18n-manager"),
et = require("elementtree"),
_config_doc,
_self,
_predefinedFeatures;

@@ -625,6 +627,9 @@ function processResult(data, session) {
//if --buildId was specified, it takes precedence
processBuildID(widgetConfig, session);

//store any config-file element injections
widgetConfig.configFileInjections = _config_doc.findall("config-file");

return widgetConfig;
}

@@ -667,6 +672,9 @@ _self = {
xml = utils.bufferToString(fileData),
parser = new xml2js.Parser({trim: true, normalize: true, explicitRoot: false});

//Used for config-file injections
_config_doc = new et.ElementTree(et.XML(xml));

init();

//parse xml file data
@@ -26,10 +26,14 @@ var childProcess = require("child_process"),
localize = require("./localize"),
pkgrUtils = require("./packager-utils"),
i18nMgr = require("./i18n-manager"),
et = require("elementtree"),
xmlHelper = require("./xml-helpers"),
NL = pkgrUtils.isWindows() ? "\r\n" : "\n";

function generateTabletXMLFile(session, config) {
var files = wrench.readdirSyncRecursive(session.sourceDir),
xmlData,
xmlDoc,
xmlObject = {
id : config.id,
versionNumber : config.version,
@@ -186,8 +190,21 @@ function generateTabletXMLFile(session, config) {
//Add auto orientation
xmlObject.initialWindow.autoOrients = config.autoOrientation;

pkgrUtils.writeFile(session.sourceDir, conf.BAR_DESCRIPTOR, data2xml('qnx', xmlObject));
}
xmlData = data2xml('qnx', xmlObject);

//Inject any config-file modifications for bar-descriptor.xml
if (config.configFileInjections && Array.isArray(config.configFileInjections)) {
xmlDoc = new et.ElementTree(et.XML(xmlData));
config.configFileInjections.forEach(function (config_file) {
if (config_file.attrib["parent"] && config_file.attrib["target"] && config_file.attrib["target"] === "bar-descriptor.xml") {
xmlHelper.graftXML(xmlDoc, config_file._children, config_file.attrib["parent"]);
}
});
xmlData = xmlDoc.write({indent: 4});
}

pkgrUtils.writeFile(session.sourceDir, conf.BAR_DESCRIPTOR, xmlData);
}

function generateOptionsFile(session, target, config) {
var srcFiles = wrench.readdirSyncRecursive(session.sourceDir),
@@ -0,0 +1,176 @@
/*
*
* Copyright 2013 Anis Kadri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/

/**
* contains XML utility functions, some of which are specific to elementtree
*/

var fs = require('fs')
, path = require('path')
, et = require('elementtree');

module.exports = {
moveProjFile: function(origFile, projPath, callback) {
var src = path.resolve(projPath, origFile)
, dest = src.replace('.orig', '');

fs.createReadStream(src)
.pipe(fs.createWriteStream(dest))
.on('close', callback);
},

// compare two et.XML nodes, see if they match
// compares tagName, text, attributes and children (recursively)
equalNodes: function(one, two) {
if (one.tag != two.tag) {
return false;
} else if (one.text.trim() != two.text.trim()) {
return false;
} else if (one._children.length != two._children.length) {
return false;
}

var oneAttribKeys = Object.keys(one.attrib),
twoAttribKeys = Object.keys(two.attrib),
i = 0, attribName;

if (oneAttribKeys.length != twoAttribKeys.length) {
return false;
}

for (i; i < oneAttribKeys.length; i++) {
attribName = oneAttribKeys[i];

if (one.attrib[attribName] != two.attrib[attribName]) {
return false;
}
}

for (i; i < one._children.length; i++) {
if (!module.exports.equalNodes(one._children[i], two._children[i])) {
return false;
}
}

return true;
},

// adds node to doc at selector, creating parent if it doesn't exist
graftXML: function(doc, nodes, selector) {
var parent = resolveParent(doc, selector);
if (!parent) {
//Try to create the parent recursively if necessary
try {
var parentToCreate = et.XML("<" + path.basename(selector) + ">"),
parentSelector = path.dirname(selector);

this.graftXML(doc, [parentToCreate], parentSelector);
} catch (e) {
return false;
}
parent = resolveParent(doc, selector);
if (!parent) return false;
}

nodes.forEach(function (node) {
// check if child is unique first
if (uniqueChild(node, parent)) {
parent.append(node);
}
});

return true;
},

// removes node from doc at selector
pruneXML: function(doc, nodes, selector) {
var parent = resolveParent(doc, selector);
if (!parent) return false;

nodes.forEach(function (node) {
var matchingKid = null;
if ((matchingKid = findChild(node, parent)) != null) {
// stupid elementtree takes an index argument it doesn't use
// and does not conform to the python lib
parent.remove(0, matchingKid);
}
});

return true;
},

parseElementtreeSync: function (filename) {
var contents = fs.readFileSync(filename, 'utf-8').replace("\ufeff", "");;
return new et.ElementTree(et.XML(contents));
}
};

function findChild(node, parent) {
var matchingKids = parent.findall(node.tag)
, i, j;

for (i = 0, j = matchingKids.length ; i < j ; i++) {
if (module.exports.equalNodes(node, matchingKids[i])) {
return matchingKids[i];
}
}
return null;
}

function uniqueChild(node, parent) {
var matchingKids = parent.findall(node.tag)
, i = 0;

if (matchingKids.length == 0) {
return true;
} else {
for (i; i < matchingKids.length; i++) {
if (module.exports.equalNodes(node, matchingKids[i])) {
return false;
}
}
return true;
}
}

var ROOT = /^\/([^\/]*)/,
ABSOLUTE = /^\/([^\/]*)\/(.*)/;
function resolveParent(doc, selector) {
var parent, tagName, subSelector;

// handle absolute selector (which elementtree doesn't like)
if (ROOT.test(selector)) {
tagName = selector.match(ROOT)[1];
// test for wildcard "any-tag" root selector
if (tagName == '*' || tagName === doc._root.tag) {
parent = doc._root;

// could be an absolute path, but not selecting the root
if (ABSOLUTE.test(selector)) {
subSelector = selector.match(ABSOLUTE)[2];
parent = parent.find(subSelector)
}
} else {
return false;
}
} else {
parent = doc.find(selector)
}
return parent;
}

0 comments on commit 1639fc1

Please sign in to comment.