etc/cli-scripts/drift.js | 164 ----------
etc/cli-scripts/measurement_utils.js | 134 --------
etc/cli-scripts/util.js | 95 -----
modules/enterprise/remoting/cli/src/main/samples/README.txt | 24 +
modules/enterprise/remoting/cli/src/main/samples/drift.js | 164 ++++++++++
modules/enterprise/remoting/cli/src/main/samples/measurement_utils.js | 134 ++++++++
modules/enterprise/remoting/cli/src/main/samples/util.js | 95 +++++
modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml | 11
8 files changed, 428 insertions(+), 393 deletions(-)
New commits:
commit d2b1f45803c91eec3a8eb962d36e8b1ca649609d
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Aug 29 14:33:18 2011 -0400
Package sample/demo scripts with CLI
diff --git a/etc/cli-scripts/drift.js b/etc/cli-scripts/drift.js
deleted file mode 100644
index 5a1e6e0a..0000000
--- a/etc/cli-scripts/drift.js
+++ /dev/null
@@ -1,164 +0,0 @@
-// This script has a dependency on rhq/etc/cl-scripts/util.js. The following
-// command needs to be run in order to load the functions in util.js:
-//
-// exec -f /path/to/rhq/etc/cli-scripts/util.js
-//
-// Then the same exec command can be run to load functions in this script.
-
-function createSnapshot(rid, cname) {
- var config = findDriftConfig(rid, function(c) { return cname.equals(c.name) });
-
- var criteria = GenericDriftChangeSetCriteria();
- criteria.addFilterResourceId(rid);
- criteria.addFilterDriftConfigurationId(config.id);
-
- if (arguments.length > 2) {
- var filters = arguments[2];
- for (key in filters) {
- criteria['addFilter' + key[0].toUpperCase() +
key.substring(1)](filters[key]);
- }
- }
-
- return DriftManager.createSnapshot(criteria);
-}
-
-function findDriftConfig(rid, filter) {
- var criteria = ResourceCriteria();
- criteria.addFilterId(rid);
- criteria.fetchDriftConfigurations(true);
-
- var resources = ResourceManager.findResourcesByCriteria(criteria);
- var resource = resources.get(0);
-
- return find(resource.driftConfigurations, function(config) {
- return filter(DriftConfiguration(config));
- });
-}
-
-function diff(s1, s2) {
- var theDiff = s1.diff(s2);
-
- if (arguments.length > 2) {
- var path = arguments[2];
-
- if (theDiff.elementsInConflict.size() == 0) {
- // If the snapshot diff reports no files in conflict, then there
- // is no need to call the server to perform the file diff. We can
- // instead return quickly.
- println("There are no differences to report");
- return "";
- }
-
- var pathFilter = function(entry) { return entry.path == path; };
- var e1 = find(s1.entries, pathFilter);
- var e2 = find(s2.entries, pathFilter);
-
- var fileDiff = DriftManager.generateUnifiedDiff(e1, e2);
- foreach(fileDiff.diff, println);
- return "";
- }
-
- function printEntry(entry) {
- println(entry.newDriftFile.hashId + '\t' + entry.path);
- }
-
- function report(header, elements) {
- println(header + ':');
- foreach(elements, printEntry);
- println('\n');
- }
-
- report('elements in conflict', theDiff.elementsInConflict);
- report('elements not in left', theDiff.elementsNotInLeft);
- report('elements not in right', theDiff.elementsNotInRight);
-}
-
-function fetchHistory(rid, configName, path) {
- function History() {
- var entries = [];
-
- this.echo = function(msg) {println(msg);}
-
- function findDrift(version) {
- return find(entries, function(drift) {
- return drift.changeSet.version == version
- });
- }
-
-
- var generate = function() {
- entries = [];
- var criteria = GenericDriftCriteria();
- criteria.addFilterResourceIds([rid]);
- criteria.fetchChangeSet(true);
- criteria.addFilterPath(path);
-
- var drifts = DriftManager.findDriftsByCriteria(criteria);
- foreach(drifts, function(drift) {
- if (drift.changeSet.driftConfiguration.name == configName &&
- drift.path == path) {
- entries.push(drift);
- }
- });
-
- entries.sort(function(d1, d2) {
- return d1.changeSet.version <= d2.changeSet.version
- });
- }
-
- this.list = function() {
- var format = java.text.DateFormat.getDateTimeInstance();
- println(path + "\n-----------------------------------");
- foreach(entries, function(drift) {
- println(drift.changeSet.version + "\t" + format.format(drift.ctime));
- });
- }
-
- this.view = function(version) {
- var drift = findDrift(version);
- if (drift == null) {
- return "Could not find version " + version;
- }
- return DriftManager.getDriftFileBits(drift.newDriftFile.hashId);
- }
-
- this.compare = function(v1, v2) {
- var d1 = findDrift(v1);
- if (d1 == null) {
- return "Could not find version " + v1;
- }
- var d2 = findDrift(v2);
- if (d2 == null) {
- return "Could not find version " + v2;
- }
- var fileDiff = DriftManager.generateUnifiedDiff(d1, d2);
- foreach(fileDiff.diff, println);
- }
-
- generate();
- }
-
- return new History();
-
-/*
- var criteria = GenericDriftCriteria();
- criteria.addFilterResourceIds([rid]);
- criteria.fetchChangeSet(true);
- criteria.addFilterPath(path);
-
- var drifts = DriftManager.findDriftsByCriteria(criteria);
- var history = [];
- foreach(drifts, function(drift) {
- if (drift.changeSet.driftConfiguration.name == configName &&
- drift.path == path) {
- history.push(drift);
- }
- });
-
- history.sort(function(d1, d2) {
- return d1.changeSet.version <= d2.changeSet.version
- });
-
- return history;
-*/
-}
diff --git a/etc/cli-scripts/measurement_utils.js b/etc/cli-scripts/measurement_utils.js
deleted file mode 100644
index 261aa8e..0000000
--- a/etc/cli-scripts/measurement_utils.js
+++ /dev/null
@@ -1,134 +0,0 @@
-testUpdates = {
- context: 'Resource',
- id: 10033,
- schedules: {
- 'Late Collections': interval(15, minutes),
- 'Failed Collections per Minute': interval(15, minutes),
- 'Currently Schedule Measurements': 'enabled'
- }
-}
-
-testGroupUpdates = {
- context: 'Group',
- id: 10031,
- schedules: {
- 'Used Swap Space': 'disabled',
- 'Total Memory': interval(3, minutes)
- }
-}
-
-/**
- * MeasurementModule is a class that provides properties and methods for working with
- * measurements.
- */
-function MeasurementModule() {
-
- /**
- * Performs the actual updates, calling MeasurementScheduleManager.
- *
- * @param updates
- * @param criteria
- * @param enableSchedules
- * @param disableSchedules
- * @param updateSchedules
- */
- function doScheduleUpdates(updates, criteria, enableSchedules, disableSchedules,
updateSchedules) {
- criteria.fetchDefinition(true);
- var schedules = MeasurementScheduleManager.findSchedulesByCriteria(criteria);
-
- foreach(schedules, function (schedule) {
- var measurementName = schedule.definition.displayName;
-
- if (updates.schedules[measurementName]) {
- switch (updates.schedules[measurementName]) {
- case 'enabled':
- MeasurementScheduleManager[enableSchedules](updates.id,
[schedule.definition.id]);
- break;
- case 'disabled':
- MeasurementScheduleManager[disableSchedules](updates.id,
- [schedule.definition.id]);
- break;
- default:
- var interval = updates.schedules[measurementName];
- MeasurementScheduleManager[updateSchedules](updates.id,
- [schedule.definition.id], interval);
- }
- }
- });
-
- }
-
- /**
- * Intended for use with the interval method.
- */
- this.time = {
- seconds: 1000,
- minutes: 60 * seconds,
- hours: 60 * minutes
- }
-
- /**
- * A helper method that calculates a shedule's interval in milliseconds
- * @param num
- * @param time
- */
- this.interval = function (num, time) {
- return num * time;
- }
-
- /**
- * Updates the metric schedule as specified in the updates object. The object is
expected
- * to contain three properties or keys. The first of these required keys is
<context>.
- * Accepted values are the strings 'Resource' or 'Group'.
- *
- * The next required key is <id>, and its values is expected to be an integer.
The
- * interpretation of its values is dependent on the value of <context>. When the
value of
- * <context> is 'Resource', then <id> is treated as a resource id.
If the value of
- * <context> is 'Group', then <id> is treated as a compatible group
id.
- *
- * The third required key is <schedules>, and it a nested object that specifies
the
- * schedules to be updated. The keys of <schedules> are the measurement display
names.
- * Expected values are 'enabled', 'disabled', or an integer which
specifies the
- * collection interval in milliseconds.
- *
- * Here is an example to illustrate what the updates object should look like:
- *
- * resourceSchedulesUpdates = {
- * context: 'Resource',
- * id: 123,
- * schedules: {
- * 'Measurement A': 'enabled',
- * 'Measurement B': 'disabled,
- * 'Measurement C': interval(20, time.minutes)
- * }
- * }
- *
- * @param updates The updates to perform
- */
- this.updateSchedules = function (updates) {
- if (!updates.id) {
- throw '<id> is a required property';
- }
-
- if (!updates.schedules) {
- throw '<schedules> is a required property';
- }
-
- if (updates.context == 'Resource') {
- var criteria = MeasurementScheduleCriteria();
- criteria.addFilterResourceId(updates.id);
- doScheduleUpdates(updates, criteria, 'enableSchedulesForResource',
- 'disableSchedulesForResource', 'updateSchedulesForResource');
- }
- else if (updates.context == 'Group') {
- var criteria = MeasurementScheduleCriteria();
- criteria.addFilterResourceGroupId(updates.id);
- doScheduleUpdates(updates, criteria, 'enableSchedulesForCompatibleGroup',
- 'disableSchedulesForCompatibleGroup',
'updateSchedulesForCompatibleGroup');
- }
- else {
- throw "Unrecognized value for context: " + updates.context + " -
expected either " +
- "<Resource> or <Group>";
- }
- }
-}
diff --git a/etc/cli-scripts/util.js b/etc/cli-scripts/util.js
deleted file mode 100644
index e0bb219..0000000
--- a/etc/cli-scripts/util.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * If obj is a JS array or a java.util.Collection, each element is passed to
- * the callback function. If obj is a java.util.Map, each map entry is passed
- * to the callback function as a key/value pair. If obj is none of the
- * aforementioned types, it is treated as a generic object and each of its
- * properties is passed to the callback function as a name/value pair.
- */
-function foreach(obj, fn) {
- if (obj instanceof Array) {
- for (i in obj) {
- fn(obj[i]);
- }
- }
- else if (obj instanceof java.util.Collection) {
- var iterator = obj.iterator();
- while (iterator.hasNext()) {
- fn(iterator.next());
- }
- }
- else if (obj instanceof java.util.Map) {
- var iterator = obj.entrySet().iterator()
- while (iterator.hasNext()) {
- var entry = iterator.next();
- fn(entry.key, entry.value);
- }
- }
- else { // assume we have a generic object
- for (i in obj) {
- fn(i, obj[i]);
- }
- }
-}
-
-/**
- * Iterates over obj similar to foreach. fn should be a predicate that evaluates
- * to true or false. The first match that is found is returned.
- */
-function find(obj, fn) {
- if (obj instanceof Array) {
- for (i in obj) {
- if (fn(obj[i])) {
- return obj[i]
- }
- }
- }
- else if (obj instanceof java.util.Collection) {
- var iterator = obj.iterator();
- while (iterator.hasNext()) {
- var next = iterator.next();
- if (fn(next)) {
- return next;
- }
- }
- }
- else if (obj instanceof java.util.Map) {
- var iterator = obj.entrySet().iterator();
- while (iterator.hasNext()) {
- var entry = iterator.next();
- if (fn(entry.key, entry.value)) {
- return {key: entry.key, value: entry.value};
- }
- }
- }
- else {
- for (i in obj) {
- if (fn(i, obj[i])) {
- return {key: i, value: obj[i]};
- }
- }
- }
- return null;
-}
-
-/**
- * Iterates over obj similar to foreach. fn should be a predicate that evaluates
- * to true or false. All of the matches are returned in a java.util.List.
- */
-function findAll(obj, fn) {
- var matches = java.util.ArrayList();
- if ((obj instanceof Array) || (obj instanceof java.util.Collection)) {
- foreach(obj, function(element) {
- if (fn(element)) {
- matches.add(element);
- }
- });
- }
- else {
- foreach(obj, function(key, value) {
- if (fn(theKey, theValue)) {
- matches.add({key: theKey, value: theValue});
- }
- });
- }
- return matches;
-}
diff --git a/modules/enterprise/remoting/cli/src/main/samples/README.txt
b/modules/enterprise/remoting/cli/src/main/samples/README.txt
new file mode 100644
index 0000000..235650a
--- /dev/null
+++ b/modules/enterprise/remoting/cli/src/main/samples/README.txt
@@ -0,0 +1,24 @@
+Overview
+---------
+The scripts located in the samples directory are intended for demonstration
+purposes to illustrate functionality and features in the CLI. These scripts
+have not undergone the same level of testing as other parts of the code base.
+As such, the quality may not meet RHQ standards in some cases. Please consider
+this when using these scripts for anything other than demonstration or testing.
+
+There may be inter-dependencies between some of the scripts. There is currently
+no mechanism in place to automatically handle script-level dependencies;
+consequently, you need to make sure to run scripts in the correct order. If a
+script has a dependency on other scripts, it will be documented within the
+script itself so that you know which scripts need to be run and in what order.
+
+
+Feedback
+--------
+The CLI is still a relatively new, young feature. We welcome and encourage
+feedback. Please send questions, comments, etc. to
+rhq-users(a)lists.fedorahosted.org or and/or to
rhq-devel.lists.fedorahosted.org.
+
+Thanks
+
+RHQ development team
diff --git a/modules/enterprise/remoting/cli/src/main/samples/drift.js
b/modules/enterprise/remoting/cli/src/main/samples/drift.js
new file mode 100644
index 0000000..5a1e6e0a
--- /dev/null
+++ b/modules/enterprise/remoting/cli/src/main/samples/drift.js
@@ -0,0 +1,164 @@
+// This script has a dependency on rhq/etc/cl-scripts/util.js. The following
+// command needs to be run in order to load the functions in util.js:
+//
+// exec -f /path/to/rhq/etc/cli-scripts/util.js
+//
+// Then the same exec command can be run to load functions in this script.
+
+function createSnapshot(rid, cname) {
+ var config = findDriftConfig(rid, function(c) { return cname.equals(c.name) });
+
+ var criteria = GenericDriftChangeSetCriteria();
+ criteria.addFilterResourceId(rid);
+ criteria.addFilterDriftConfigurationId(config.id);
+
+ if (arguments.length > 2) {
+ var filters = arguments[2];
+ for (key in filters) {
+ criteria['addFilter' + key[0].toUpperCase() +
key.substring(1)](filters[key]);
+ }
+ }
+
+ return DriftManager.createSnapshot(criteria);
+}
+
+function findDriftConfig(rid, filter) {
+ var criteria = ResourceCriteria();
+ criteria.addFilterId(rid);
+ criteria.fetchDriftConfigurations(true);
+
+ var resources = ResourceManager.findResourcesByCriteria(criteria);
+ var resource = resources.get(0);
+
+ return find(resource.driftConfigurations, function(config) {
+ return filter(DriftConfiguration(config));
+ });
+}
+
+function diff(s1, s2) {
+ var theDiff = s1.diff(s2);
+
+ if (arguments.length > 2) {
+ var path = arguments[2];
+
+ if (theDiff.elementsInConflict.size() == 0) {
+ // If the snapshot diff reports no files in conflict, then there
+ // is no need to call the server to perform the file diff. We can
+ // instead return quickly.
+ println("There are no differences to report");
+ return "";
+ }
+
+ var pathFilter = function(entry) { return entry.path == path; };
+ var e1 = find(s1.entries, pathFilter);
+ var e2 = find(s2.entries, pathFilter);
+
+ var fileDiff = DriftManager.generateUnifiedDiff(e1, e2);
+ foreach(fileDiff.diff, println);
+ return "";
+ }
+
+ function printEntry(entry) {
+ println(entry.newDriftFile.hashId + '\t' + entry.path);
+ }
+
+ function report(header, elements) {
+ println(header + ':');
+ foreach(elements, printEntry);
+ println('\n');
+ }
+
+ report('elements in conflict', theDiff.elementsInConflict);
+ report('elements not in left', theDiff.elementsNotInLeft);
+ report('elements not in right', theDiff.elementsNotInRight);
+}
+
+function fetchHistory(rid, configName, path) {
+ function History() {
+ var entries = [];
+
+ this.echo = function(msg) {println(msg);}
+
+ function findDrift(version) {
+ return find(entries, function(drift) {
+ return drift.changeSet.version == version
+ });
+ }
+
+
+ var generate = function() {
+ entries = [];
+ var criteria = GenericDriftCriteria();
+ criteria.addFilterResourceIds([rid]);
+ criteria.fetchChangeSet(true);
+ criteria.addFilterPath(path);
+
+ var drifts = DriftManager.findDriftsByCriteria(criteria);
+ foreach(drifts, function(drift) {
+ if (drift.changeSet.driftConfiguration.name == configName &&
+ drift.path == path) {
+ entries.push(drift);
+ }
+ });
+
+ entries.sort(function(d1, d2) {
+ return d1.changeSet.version <= d2.changeSet.version
+ });
+ }
+
+ this.list = function() {
+ var format = java.text.DateFormat.getDateTimeInstance();
+ println(path + "\n-----------------------------------");
+ foreach(entries, function(drift) {
+ println(drift.changeSet.version + "\t" + format.format(drift.ctime));
+ });
+ }
+
+ this.view = function(version) {
+ var drift = findDrift(version);
+ if (drift == null) {
+ return "Could not find version " + version;
+ }
+ return DriftManager.getDriftFileBits(drift.newDriftFile.hashId);
+ }
+
+ this.compare = function(v1, v2) {
+ var d1 = findDrift(v1);
+ if (d1 == null) {
+ return "Could not find version " + v1;
+ }
+ var d2 = findDrift(v2);
+ if (d2 == null) {
+ return "Could not find version " + v2;
+ }
+ var fileDiff = DriftManager.generateUnifiedDiff(d1, d2);
+ foreach(fileDiff.diff, println);
+ }
+
+ generate();
+ }
+
+ return new History();
+
+/*
+ var criteria = GenericDriftCriteria();
+ criteria.addFilterResourceIds([rid]);
+ criteria.fetchChangeSet(true);
+ criteria.addFilterPath(path);
+
+ var drifts = DriftManager.findDriftsByCriteria(criteria);
+ var history = [];
+ foreach(drifts, function(drift) {
+ if (drift.changeSet.driftConfiguration.name == configName &&
+ drift.path == path) {
+ history.push(drift);
+ }
+ });
+
+ history.sort(function(d1, d2) {
+ return d1.changeSet.version <= d2.changeSet.version
+ });
+
+ return history;
+*/
+}
diff --git a/modules/enterprise/remoting/cli/src/main/samples/measurement_utils.js
b/modules/enterprise/remoting/cli/src/main/samples/measurement_utils.js
new file mode 100644
index 0000000..261aa8e
--- /dev/null
+++ b/modules/enterprise/remoting/cli/src/main/samples/measurement_utils.js
@@ -0,0 +1,134 @@
+testUpdates = {
+ context: 'Resource',
+ id: 10033,
+ schedules: {
+ 'Late Collections': interval(15, minutes),
+ 'Failed Collections per Minute': interval(15, minutes),
+ 'Currently Schedule Measurements': 'enabled'
+ }
+}
+
+testGroupUpdates = {
+ context: 'Group',
+ id: 10031,
+ schedules: {
+ 'Used Swap Space': 'disabled',
+ 'Total Memory': interval(3, minutes)
+ }
+}
+
+/**
+ * MeasurementModule is a class that provides properties and methods for working with
+ * measurements.
+ */
+function MeasurementModule() {
+
+ /**
+ * Performs the actual updates, calling MeasurementScheduleManager.
+ *
+ * @param updates
+ * @param criteria
+ * @param enableSchedules
+ * @param disableSchedules
+ * @param updateSchedules
+ */
+ function doScheduleUpdates(updates, criteria, enableSchedules, disableSchedules,
updateSchedules) {
+ criteria.fetchDefinition(true);
+ var schedules = MeasurementScheduleManager.findSchedulesByCriteria(criteria);
+
+ foreach(schedules, function (schedule) {
+ var measurementName = schedule.definition.displayName;
+
+ if (updates.schedules[measurementName]) {
+ switch (updates.schedules[measurementName]) {
+ case 'enabled':
+ MeasurementScheduleManager[enableSchedules](updates.id,
[schedule.definition.id]);
+ break;
+ case 'disabled':
+ MeasurementScheduleManager[disableSchedules](updates.id,
+ [schedule.definition.id]);
+ break;
+ default:
+ var interval = updates.schedules[measurementName];
+ MeasurementScheduleManager[updateSchedules](updates.id,
+ [schedule.definition.id], interval);
+ }
+ }
+ });
+
+ }
+
+ /**
+ * Intended for use with the interval method.
+ */
+ this.time = {
+ seconds: 1000,
+ minutes: 60 * seconds,
+ hours: 60 * minutes
+ }
+
+ /**
+ * A helper method that calculates a shedule's interval in milliseconds
+ * @param num
+ * @param time
+ */
+ this.interval = function (num, time) {
+ return num * time;
+ }
+
+ /**
+ * Updates the metric schedule as specified in the updates object. The object is
expected
+ * to contain three properties or keys. The first of these required keys is
<context>.
+ * Accepted values are the strings 'Resource' or 'Group'.
+ *
+ * The next required key is <id>, and its values is expected to be an integer.
The
+ * interpretation of its values is dependent on the value of <context>. When the
value of
+ * <context> is 'Resource', then <id> is treated as a resource id.
If the value of
+ * <context> is 'Group', then <id> is treated as a compatible group
id.
+ *
+ * The third required key is <schedules>, and it a nested object that specifies
the
+ * schedules to be updated. The keys of <schedules> are the measurement display
names.
+ * Expected values are 'enabled', 'disabled', or an integer which
specifies the
+ * collection interval in milliseconds.
+ *
+ * Here is an example to illustrate what the updates object should look like:
+ *
+ * resourceSchedulesUpdates = {
+ * context: 'Resource',
+ * id: 123,
+ * schedules: {
+ * 'Measurement A': 'enabled',
+ * 'Measurement B': 'disabled,
+ * 'Measurement C': interval(20, time.minutes)
+ * }
+ * }
+ *
+ * @param updates The updates to perform
+ */
+ this.updateSchedules = function (updates) {
+ if (!updates.id) {
+ throw '<id> is a required property';
+ }
+
+ if (!updates.schedules) {
+ throw '<schedules> is a required property';
+ }
+
+ if (updates.context == 'Resource') {
+ var criteria = MeasurementScheduleCriteria();
+ criteria.addFilterResourceId(updates.id);
+ doScheduleUpdates(updates, criteria, 'enableSchedulesForResource',
+ 'disableSchedulesForResource', 'updateSchedulesForResource');
+ }
+ else if (updates.context == 'Group') {
+ var criteria = MeasurementScheduleCriteria();
+ criteria.addFilterResourceGroupId(updates.id);
+ doScheduleUpdates(updates, criteria, 'enableSchedulesForCompatibleGroup',
+ 'disableSchedulesForCompatibleGroup',
'updateSchedulesForCompatibleGroup');
+ }
+ else {
+ throw "Unrecognized value for context: " + updates.context + " -
expected either " +
+ "<Resource> or <Group>";
+ }
+ }
+}
diff --git a/modules/enterprise/remoting/cli/src/main/samples/util.js
b/modules/enterprise/remoting/cli/src/main/samples/util.js
new file mode 100644
index 0000000..e0bb219
--- /dev/null
+++ b/modules/enterprise/remoting/cli/src/main/samples/util.js
@@ -0,0 +1,95 @@
+/**
+ * If obj is a JS array or a java.util.Collection, each element is passed to
+ * the callback function. If obj is a java.util.Map, each map entry is passed
+ * to the callback function as a key/value pair. If obj is none of the
+ * aforementioned types, it is treated as a generic object and each of its
+ * properties is passed to the callback function as a name/value pair.
+ */
+function foreach(obj, fn) {
+ if (obj instanceof Array) {
+ for (i in obj) {
+ fn(obj[i]);
+ }
+ }
+ else if (obj instanceof java.util.Collection) {
+ var iterator = obj.iterator();
+ while (iterator.hasNext()) {
+ fn(iterator.next());
+ }
+ }
+ else if (obj instanceof java.util.Map) {
+ var iterator = obj.entrySet().iterator()
+ while (iterator.hasNext()) {
+ var entry = iterator.next();
+ fn(entry.key, entry.value);
+ }
+ }
+ else { // assume we have a generic object
+ for (i in obj) {
+ fn(i, obj[i]);
+ }
+ }
+}
+
+/**
+ * Iterates over obj similar to foreach. fn should be a predicate that evaluates
+ * to true or false. The first match that is found is returned.
+ */
+function find(obj, fn) {
+ if (obj instanceof Array) {
+ for (i in obj) {
+ if (fn(obj[i])) {
+ return obj[i]
+ }
+ }
+ }
+ else if (obj instanceof java.util.Collection) {
+ var iterator = obj.iterator();
+ while (iterator.hasNext()) {
+ var next = iterator.next();
+ if (fn(next)) {
+ return next;
+ }
+ }
+ }
+ else if (obj instanceof java.util.Map) {
+ var iterator = obj.entrySet().iterator();
+ while (iterator.hasNext()) {
+ var entry = iterator.next();
+ if (fn(entry.key, entry.value)) {
+ return {key: entry.key, value: entry.value};
+ }
+ }
+ }
+ else {
+ for (i in obj) {
+ if (fn(i, obj[i])) {
+ return {key: i, value: obj[i]};
+ }
+ }
+ }
+ return null;
+}
+
+/**
+ * Iterates over obj similar to foreach. fn should be a predicate that evaluates
+ * to true or false. All of the matches are returned in a java.util.List.
+ */
+function findAll(obj, fn) {
+ var matches = java.util.ArrayList();
+ if ((obj instanceof Array) || (obj instanceof java.util.Collection)) {
+ foreach(obj, function(element) {
+ if (fn(element)) {
+ matches.add(element);
+ }
+ });
+ }
+ else {
+ foreach(obj, function(key, value) {
+ if (fn(theKey, theValue)) {
+ matches.add({key: theKey, value: theValue});
+ }
+ });
+ }
+ return matches;
+}
diff --git a/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml
b/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml
index baf99e5..803afe6 100644
--- a/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml
+++ b/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml
@@ -8,6 +8,7 @@
<property name="conf.home" location="${output.dir}/conf" />
<property name="jboss.home"
location="${basedir}/target/jboss-${jboss.version}" />
<property name="lib.home" location="${output.dir}/lib" />
+ <property name="samples.home"
location="${output.dir}/samples"/>
<target name="prepare-dist">
<condition property="exclude.cli.jar" value="true">
@@ -20,6 +21,7 @@
<antcall target="prepare-bin-dir" />
<antcall target="prepare-conf-dir" />
<antcall target="prepare-lib-dir" />
+ <antcall target="prepare-samples-dir" />
</target>
<target name="prepare-bin-dir">
@@ -68,5 +70,14 @@
<copy
file="${settings.localRepository}/hibernate-annotations/hibernate-annotations/${hibernate-annotations.version}/hibernate-annotations-${hibernate-annotations.version}.jar"
todir="${lib.home}" verbose="true" />
</target>
+ <target name="prepare-samples-dir">
+ <echo>*** Creating samples dir...</echo>
+ <mkdir dir="${samples.home}" />
+ <echo>*** Populating sample scripts...</echo>
+ <copy verbose="true" toDir="${samples.home}">
+ <fileset dir="${basedir}/src/main/samples/"
includes="*.*" />
+ </copy>
+ </target>
+
</project>