diff --git a/.gitignore b/.gitignore
index 38cf0da..6b17ee7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@ node_modules/
.idea/
*.iml
DS_Store
+.DS_Store
+/.project
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/definition.json b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/definition.json
new file mode 100644
index 0000000..e6f176e
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/definition.json
@@ -0,0 +1,4 @@
+{
+ "id": "f5ef5eed-f56e-5073-87bb-2fa88f5a3b49",
+ "name" : "JiveWorld '14 Demo"
+}
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/actionView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/actionView.html
new file mode 100644
index 0000000..ee99a47
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/actionView.html
@@ -0,0 +1,12 @@
+
+action view
+
+
+
+
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/app.xml b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/app.xml
new file mode 100644
index 0000000..cd6afc5
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/app.xml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/bangView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/bangView.html
new file mode 100644
index 0000000..02e2cde
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/bangView.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/canvas.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/canvas.html
new file mode 100644
index 0000000..7e631fd
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/canvas.html
@@ -0,0 +1,20 @@
+
+
+
+ A regular blank canvas
+
+
+
+
+
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/contentView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/contentView.html
new file mode 100644
index 0000000..8befba6
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/contentView.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/embeddedView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/embeddedView.html
new file mode 100644
index 0000000..a815eb1
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/embeddedView.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ Saved context for / :
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/extStreamAppView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/extStreamAppView.html
new file mode 100644
index 0000000..09fbdd1
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/extStreamAppView.html
@@ -0,0 +1,18 @@
+
+
+
+
+External Stream App View
+
+
+
+
+
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-128.png b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-128.png
new file mode 100644
index 0000000..01da9d6
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-128.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-16.png b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-16.png
new file mode 100644
index 0000000..64a7055
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-16.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-32.png b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-32.png
new file mode 100644
index 0000000..8cd5758
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-32.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-48.png b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-48.png
new file mode 100644
index 0000000..c1d9410
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/images/jw-48.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/javascripts/main.js b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/javascripts/main.js
new file mode 100644
index 0000000..bc25273
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/javascripts/main.js
@@ -0,0 +1,6 @@
+gadgets.util.registerOnLoadHandler(function() {
+ // add code that should run on page load here
+
+ // resize app window to fit content
+ // gadgets.window.adjustHeight();
+});
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeActionView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeActionView.html
new file mode 100644
index 0000000..d9fcd64
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeActionView.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeSettingsView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeSettingsView.html
new file mode 100644
index 0000000..849d3c4
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeSettingsView.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeTabView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeTabView.html
new file mode 100644
index 0000000..ee05e05
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/placeTabView.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/profileView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/profileView.html
new file mode 100644
index 0000000..cbf7571
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/profileView.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/stylesheets/main.css b/jive-sdk-service/generator/examples/example-jw14-apps/apps/demoapp/public/stylesheets/main.css
new file mode 100644
index 0000000..e69de29
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/definition.json b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/definition.json
new file mode 100644
index 0000000..0915e70
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/definition.json
@@ -0,0 +1,4 @@
+{
+ "id": "8d6df633-f0ba-54c4-b950-418c19cea08c",
+ "name" : "JiveWorld '14 Conditional Display Demo"
+}
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/app.xml b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/app.xml
new file mode 100644
index 0000000..b62f26a
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/app.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/filteredPlaceActionView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/filteredPlaceActionView.html
new file mode 100644
index 0000000..50a02d3
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/filteredPlaceActionView.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/filteredPlaceSettingsView.html b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/filteredPlaceSettingsView.html
new file mode 100644
index 0000000..d94411b
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/filteredPlaceSettingsView.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-128.png b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-128.png
new file mode 100644
index 0000000..01da9d6
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-128.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-16.png b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-16.png
new file mode 100644
index 0000000..64a7055
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-16.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-32.png b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-32.png
new file mode 100644
index 0000000..8cd5758
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-32.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-48.png b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-48.png
new file mode 100644
index 0000000..c1d9410
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/apps/filterdemo/public/images/jw-48.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/jiveclientconfiguration.json b/jive-sdk-service/generator/examples/example-jw14-apps/jiveclientconfiguration.json
new file mode 100644
index 0000000..ed31eef
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/jiveclientconfiguration.json
@@ -0,0 +1,8 @@
+{
+ "clientUrl": "tenancy://jive!services.jwdemo.serviceURL",
+ "extensionInfo" : {
+ "uuid" : "4ff946ab-b5f5-43be-86b9-70135e072ddd",
+ "name": "JiveWorld14 Demo",
+ "description": "JiveWorld14 Demo"
+ }
+}
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/package.json b/jive-sdk-service/generator/examples/example-jw14-apps/package.json
new file mode 100644
index 0000000..2953bfe
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "jw14demo",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "express": "3.1.0",
+ "jive-sdk":"*",
+ "mustache": "0.7.2",
+ "handlebars": "2.0.0-alpha.2",
+ "consolidate": "0.9.0",
+ "poplib" : "0.1.5",
+ "q": "0.9.3",
+ "multipart-parser" : "0.0.2",
+ "q-io": "1.6.x",
+ "request": "2.27.0",
+ "xml2js": "0.2.8"
+ }
+}
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/backend/routes/configure/get.js b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/backend/routes/configure/get.js
new file mode 100644
index 0000000..61d121a
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/backend/routes/configure/get.js
@@ -0,0 +1,3 @@
+exports.route = function(req, res){
+ res.render('configure.html', {});
+};
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/backend/services.js b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/backend/services.js
new file mode 100644
index 0000000..51988a6
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/backend/services.js
@@ -0,0 +1,53 @@
+var jive = require('jive-sdk');
+var scheduler = new jive.scheduler.memory();
+
+
+var sendActivity = function() {
+
+ jive.extstreams.findByDefinitionName('demo-activity').then(function(instances) {
+ if (instances) {
+ instances.forEach(function(instance) {
+
+ var time = new Date();
+
+ var data = {
+ "activity": {
+ "action": {
+ "name": "posted",
+ "description": "Activity " + time
+ },
+ "actor": {
+ "name": "JiveWorld14 Demo",
+ "email": "user2@localhost"
+ },
+ "object": {
+ "type": "website",
+ "url": "http://www.google.com",
+ "image": "http://localhost:8090/demo-activity/images/jw-128.png",
+ "title": "Activity " + time,
+ "description": "Activity " + time
+ },
+ "jive": {
+ "app": {
+ "appUUID": "f5ef5eed-f56e-5073-87bb-2fa88f5a3b49",
+ "view": "extStreamAppView",
+ "context": {
+ time: time
+ }
+ }
+ }
+ }
+ };
+
+ jive.extstreams.pushActivity(instance, data);
+ });
+ }
+ });
+
+};
+
+exports.onBootstrap = function() {
+ var task = new jive.tasks.build(sendActivity, 60000);
+
+ jive.tasks.schedule(task, scheduler);
+};
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/definition.json b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/definition.json
new file mode 100644
index 0000000..861e176
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/definition.json
@@ -0,0 +1,12 @@
+{
+ "displayName" : "JiveWorld14 Activity Stream",
+ "name" : "demo-activity",
+ "description" : "Demonstration of embedding Apps in External Activity",
+ "style" : "ACTIVITY",
+ "config": "%serviceURL%/demo-activity/configure",
+ "icons" : {
+ "16" : "%serviceURL%/demo-activity/images/jw-16.png",
+ "48" : "%serviceURL%/demo-activity/images/jw-48.png",
+ "128" : "%serviceURL%/demo-activity/images/jw-128.png"
+ }
+}
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/configure.html b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/configure.html
new file mode 100644
index 0000000..88f1783
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/configure.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-128.png b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-128.png
new file mode 100644
index 0000000..01da9d6
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-128.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-16.png b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-16.png
new file mode 100644
index 0000000..64a7055
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-16.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-32.png b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-32.png
new file mode 100644
index 0000000..8cd5758
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-32.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-48.png b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-48.png
new file mode 100644
index 0000000..c1d9410
Binary files /dev/null and b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/demo-activity/public/images/jw-48.png differ
diff --git a/jive-sdk-service/generator/examples/example-jw14-apps/tiles/templates.json b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/templates.json
new file mode 100644
index 0000000..9b67dbc
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-apps/tiles/templates.json
@@ -0,0 +1,10 @@
+{
+ "default": {
+ "name": "defaultTemplate",
+ "displayName": "JiveWorld '14 Demo",
+ "description": "JiveWorld '14 Demo",
+ "tiles": [
+ "demo-activity"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/jiveclientconfiguration.json b/jive-sdk-service/generator/examples/example-jw14-tiles/jiveclientconfiguration.json
new file mode 100644
index 0000000..a27e2fa
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/jiveclientconfiguration.json
@@ -0,0 +1,10 @@
+{
+ "clientUrl": "http://localhost",
+ "port": "3000",
+ "development" : true,
+ "fileFlushInterval": 2000,
+ "uuid" : "975e3675-3d2d-4631-a2d3-2fefeeb566fb",
+ "name": "JiveWorld Purposeful Places Add-on",
+ "description": "JiveWorld14 Demo"
+
+}
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/package.json b/jive-sdk-service/generator/examples/example-jw14-tiles/package.json
new file mode 100644
index 0000000..03e70d0
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "jw14purposefulplaces",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "express": "3.1.0",
+ "jive-sdk":"*",
+ "mustache": "0.7.2",
+ "consolidate": "0.9.0",
+ "poplib" : "0.1.5",
+ "q": "0.9.3",
+ "multipart-parser" : "0.0.2",
+ "q-io": "1.6.x",
+ "request": "2.27.0",
+ "xml2js": "0.2.8"
+ }
+}
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/public/stylesheets/style.css b/jive-sdk-service/generator/examples/example-jw14-tiles/public/stylesheets/style.css
new file mode 100644
index 0000000..da50c6e
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/public/stylesheets/style.css
@@ -0,0 +1,29 @@
+* {
+ font-family: Arial, sans-serif;
+}
+
+body { background-color: #eee; margin:20px; }
+label, p { display: block; margin: 0.4em 0; }
+label input, label strong { display: inline-block; width: 4em; text-align: right; }
+button { font-size: 1.15em; font-weight: bold; }
+
+.j-card .hidden {
+ display: none;
+}
+
+h2 {
+ margin-bottom: -2px;
+}
+
+h3 {
+ margin-bottom: -8px;
+}
+
+ul {
+ margin-left:0px; padding-left:20px; list-style-type:square;
+}
+
+.j-textarea {
+ width: 50%;
+ height: 512px;
+}
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/services/performanceservice/backend/routes/explicit_routes.js b/jive-sdk-service/generator/examples/example-jw14-tiles/services/performanceservice/backend/routes/explicit_routes.js
new file mode 100644
index 0000000..0f6f627
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/services/performanceservice/backend/routes/explicit_routes.js
@@ -0,0 +1,11 @@
+var jive = require('jive-sdk');
+
+exports.last = {
+ 'verb' : 'get',
+ 'route': function(req, res) {
+ res.writeHead(200);
+ var random = Math.round(Math.random() * 2499) + 1;
+ jive.logger.info('last request duration: ' + random)
+ res.end('' + random);
+ }
+};
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/lib.js b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/lib.js
new file mode 100644
index 0000000..a291c2e
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/lib.js
@@ -0,0 +1,40 @@
+var jive = require("jive-sdk"),
+ request = require("request"),
+ q = require("q");
+
+// TODO: replace with jive.service.serviceURL()
+
+exports.getPerformance = function() {
+ var deferred = q.defer(),
+ url = jive.service.serviceURL() + "/performanceservice/last";
+ request.get({uri: url, timeout: 2500}, function(err, response, body) {
+ if (err) {
+ deferred.reject();
+ } else {
+ deferred.resolve(body);
+ }
+ });
+ return deferred.promise;
+}
+
+/**
+ * [ 1, 2000, 1500, 500 ] and a 'body' responseTime
+ * example: responseTime '750' would return index 2
+ */
+exports.getRangeIndex = function(ranges, body) {
+ var responseTime = parseInt(body);
+ if (isNaN(responseTime) || responseTime < 1) {
+ return 0;
+ }
+ var result = 0, lastLimit = Number.MAX_VALUE;
+ ranges.forEach(function(limit, index) {
+ if (isNaN(limit)) {
+ limit = 1
+ }
+ if (responseTime < limit && limit < lastLimit) {
+ result = index;
+ lastLimit = limit;
+ }
+ });
+ return result;
+}
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/backend/datapusher.js b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/backend/datapusher.js
new file mode 100644
index 0000000..4f6a1f3
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/backend/datapusher.js
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2013 Jive Software
+ *
+ * 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.
+ */
+
+var jive = require("jive-sdk"),
+ store = jive.service.persistence(),
+ lib = require("../../lib"),
+ ABORT = new Error("not a failure"),
+ STORE = 'performanceNotificationCount';
+
+exports.task = [
+ {
+ 'interval' : 10000,
+ 'handler' : pushData
+ }
+];
+
+function pushData() {
+ jive.extstreams.findByDefinitionName('performance-notification')
+ .then(function(instances) {
+ if (instances) {
+ instances.forEach(processTileInstance);
+ }
+ })
+ .fail(function(error) {
+ jive.logger.error(error);
+ });
+};
+
+function processTileInstance(instance) {
+ var actualCount, responseTime;
+ lib.getPerformance()
+ .then(function(body) {
+ if (lib.getRangeIndex([0, 2000], body) !== 0) {
+ throw ABORT;
+ }
+ responseTime = body;
+ // count failures only
+ return store.find(STORE, { key:'count' });
+ })
+ .then(function(counts) {
+ var count = counts.length > 0 ? counts[0].count : 0;
+ actualCount = count + 1;
+ return store.save(STORE, 'failureCount', {
+ 'key': 'count',
+ 'count': actualCount
+ })
+ })
+ .then(function() {
+ var data = getFormattedData(actualCount, responseTime, instance);
+ jive.logger.info(
+ "pushing %s to activity stream %s, access token %s",
+ JSON.stringify(data), instance.id, instance.accessToken);
+ jive.extstreams.pushActivity(instance, data);
+ })
+ .fail(function(error) {
+ if (error && error.message !== ABORT.message) {
+ jive.logger.error(error);
+ }
+ });
+}
+
+function getFormattedData(count, responseTime, instance) {
+ return {
+ "activity": {
+ "action": {
+ "name": "posted",
+ "description": "Total number of failures " + count
+ },
+ "actor": {
+ "name": "Performance Monitoring Service",
+ "email": "perfserv@email.com"
+ },
+ "object": {
+ "type": "website",
+ "url": "http://www.monitoring-service.com/failures/" + encodeURI(instance.jiveCommunity),
+ "image": "http://placehold.it/102x102",
+ "title": "Total number of failures " + count,
+ "description": "Response time was " + responseTime +
+ "ms. For detailed failure information, click on 'Go to item'"
+ },
+ "externalID": '' + instance.id + ':' + Date.now()
+ }
+ };
+}
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/backend/routes/configure/get.js b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/backend/routes/configure/get.js
new file mode 100644
index 0000000..a435fed
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/backend/routes/configure/get.js
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Jive Software
+ *
+ * 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.
+ */
+
+var jive = require("jive-sdk");
+
+exports.route = function(req, res) {
+ res.render('configuration.html', { host: jive.service.serviceURL() });
+};
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/definition.json b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/definition.json
new file mode 100644
index 0000000..61b1f77
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/definition.json
@@ -0,0 +1,12 @@
+{
+ "sampleData" : {},
+ "displayName" : "Performance Notification",
+ "name" : "performance-notification",
+ "description" : "Lists certain performance notifications in the activity stream",
+ "style" : "ACTIVITY",
+ "icons" : {
+ "16" : "https://community.jivesoftware.com/servlet/JiveServlet/showImage/102-99994-1-1023036/j.png",
+ "48" : "https://community.jivesoftware.com/servlet/JiveServlet/showImage/102-99994-1-1023036/j.png",
+ "128" : "https://community.jivesoftware.com/servlet/JiveServlet/showImage/102-99994-1-1023036/j.png"
+ }
+}
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/public/configuration.html b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/public/configuration.html
new file mode 100644
index 0000000..0e3c113
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-notification/public/configuration.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ No configuration.
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/datapusher.js b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/datapusher.js
new file mode 100644
index 0000000..529990a
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/datapusher.js
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2013 Jive Software
+ *
+ * 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.
+ */
+
+var jive = require("jive-sdk"),
+ lib = require("../../lib"),
+ tileData = require("../definition.json").sampleData,
+ defaultRanges = [ 1, 2000, 1500, 1000 ];
+
+/**
+ * Schedules the tile update task to automatically fire every 10 seconds
+ */
+exports.task = [
+ {
+ 'interval' : 10000,
+ 'handler' : pushData
+ }
+];
+
+/**
+ * Defines event handlers for the tile life cycle events
+ */
+exports.eventHandlers = [
+
+ // process tile instance whenever a new one is registered with the service
+ {
+ 'event' : jive.constants.globalEventNames.NEW_INSTANCE,
+ 'handler' : processTileInstance
+ },
+
+ // process tile instance whenever an existing tile instance is updated
+ {
+ 'event' : jive.constants.globalEventNames.INSTANCE_UPDATED,
+ 'handler' : processTileInstance
+ }
+];
+
+function pushData() {
+ jive.tiles.findByDefinitionName('performance-tile')
+ .then( function(instances) {
+ if (instances) {
+ instances.forEach(processTileInstance);
+ }
+ })
+ .fail(function(error) {
+ jive.logger.error(error);
+ });
+}
+
+function processTileInstance(instance) {
+ lib.getPerformance()
+ .then(function(body) {
+ var index = lib.getRangeIndex(instance.config.ranges || defaultRanges, body);
+ pushSection(index, body);
+ })
+ .fail(function(error) {
+ jive.logger.error(error);
+ pushSection(0)
+ });
+
+ function pushSection(index, responseTime) {
+ var label = tileData.sections[index].label;
+ responseTime = responseTime ? responseTime + "ms" : "failure";
+ var message = tileData.message + ": " + responseTime;
+ jive.logger.info("update tile %s to index %d with label '%s' and message: %s",
+ instance.id, index, label, message);
+ var dataToPush = {
+ data: {
+ "message": message,
+ "sections": tileData.sections,
+ "activeIndex": index,
+ "status": label,
+ "action": {
+ "text": "Discuss the current performance",
+ "context": {
+ "responseTime": responseTime,
+ "level": index,
+ "label": label
+ }
+ }
+ }
+ };
+ jive.tiles.pushData(instance, dataToPush);
+ }
+}
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/routes/action/get.js b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/routes/action/get.js
new file mode 100644
index 0000000..4df355b
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/routes/action/get.js
@@ -0,0 +1,5 @@
+var jive = require("jive-sdk");
+
+exports.route = function(req, res){
+ res.render('action.html', { host: jive.service.serviceURL() });
+};
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/routes/configure/get.js b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/routes/configure/get.js
new file mode 100644
index 0000000..5727e71
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/backend/routes/configure/get.js
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Jive Software
+ *
+ * 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.
+ */
+
+var jive = require("jive-sdk");
+
+exports.route = function(req, res){
+ res.render('configuration.html', { host: jive.service.serviceURL() });
+};
\ No newline at end of file
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/definition.json b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/definition.json
new file mode 100644
index 0000000..d9b49c1
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/definition.json
@@ -0,0 +1,35 @@
+{
+ "sampleData" : {
+ "message": "Remote Service Performance",
+ "sections": [
+ {
+ "color": "#021677",
+ "label": "Trouble!"
+ },
+ {
+ "color": "#5a2bac",
+ "label": "Slow!"
+ },
+ {
+ "color": "#0088e1",
+ "label": "Good"
+ },
+ {
+ "color": "#00c4dc",
+ "label": "Fast"
+ }
+ ],
+ "activeIndex": 3,
+ "status": "Fast"
+ },
+ "displayName": "Remote Performance",
+ "name": "performance-tile",
+ "description": "Shows performance indicators of a remote service",
+ "action": "/performance-tile/action",
+ "style" : "GAUGE",
+ "icons" : {
+ "16" : "https://community.jivesoftware.com/servlet/JiveServlet/showImage/102-99994-1-1023036/j.png",
+ "48" : "https://community.jivesoftware.com/servlet/JiveServlet/showImage/102-99994-1-1023036/j.png",
+ "128" : "https://community.jivesoftware.com/servlet/JiveServlet/showImage/102-99994-1-1023036/j.png"
+ }
+}
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/action.html b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/action.html
new file mode 100644
index 0000000..15e5834
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/action.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
Discuss this performance level
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/configuration.html b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/configuration.html
new file mode 100644
index 0000000..8af49c6
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/configuration.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/javascripts/action.js b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/javascripts/action.js
new file mode 100644
index 0000000..7cd3ff7
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/javascripts/action.js
@@ -0,0 +1,48 @@
+/* https://community.jivesoftware.com/docs/DOC-129789 */
+
+jive.tile.onOpen(function(context) {
+ if (typeof context === "string" ) {
+ context = JSON.parse(context);
+ }
+ if (typeof context === "string" ) {
+ context = JSON.parse(context);
+ }
+ var messageTemplate =
+ "Response performance was " + context.responseTime +
+ ", meaning it was " + context.label + ".";
+ $('#template_content').html(messageTemplate);
+
+ gadgets.window.adjustHeight();
+
+ $('#btn_cancel').click(function() {
+ jive.tile.close();
+ });
+
+ var submitButton = $('#btn_submit').click(function() {
+ var customMessage = $('#custom_message').val() || "";
+ submitButton.parent().html("creating discussion ...");
+ jive.tile.getContainer(function(container) {
+ var containerRef = container.resources.self.ref;
+ var discussion = {
+ "content": {
+ "type": "text/html",
+ "text": "" + messageTemplate + "
" + customMessage + "
"
+ },
+ "subject": "Discuss Performance '" + context.label + "', " + context.responseTime,
+ "visibility": "place",
+ "parent": containerRef
+ }
+ /* https://developers.jivesoftware.com/api/v3/cloud/js/discussions.html */
+ /* http://opensocial-resources.googlecode.com/svn/spec/1.0/Core-Gadget.xml#osapi.Request */
+ var request = osapi.jive.corev3.discussions.create(discussion);
+ /* http://json-rpc.org/wiki/specification */
+ request.execute(function(response) {
+ if (response.error) {
+ alert(JSON.stringify(response.error));
+ return;
+ }
+ jive.tile.close();
+ });
+ });
+ });
+});
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/javascripts/main.js b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/javascripts/main.js
new file mode 100644
index 0000000..d53dd5d
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/performance-tile/public/javascripts/main.js
@@ -0,0 +1,22 @@
+jive.tile.onOpen(function(config, options) {
+ gadgets.window.adjustHeight();
+ if (typeof config === "string") {
+ config = JSON.parse(config);
+ }
+ var ranges = config.ranges || [ null, 2000, 1500, 1000 ];
+ // fill form with current settings
+ ranges.forEach(function(limit, index) {
+ if (limit) {
+ $("#limit_" + index).val(limit);
+ }
+ });
+ $("#btn_submit").click(function() {
+ ranges.forEach(function(limit, index) {
+ if (limit) {
+ ranges[index] = parseInt($("#limit_" + index).val()) || limit;
+ }
+ });
+ config.ranges = ranges;
+ jive.tile.close(config, {} );
+ });
+});
diff --git a/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/templates.json b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/templates.json
new file mode 100644
index 0000000..2742ff6
--- /dev/null
+++ b/jive-sdk-service/generator/examples/example-jw14-tiles/tiles/templates.json
@@ -0,0 +1,10 @@
+{
+ "default": {
+ "name": "defaultTemplate",
+ "displayName": "JiveWorld Purposeful Places Add-on Template",
+ "description": "Template for Jive Node SDK-based integrations session demo",
+ "tiles": [
+ "performance-tile", "performance-notification"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/jive-sdk-service/generator/styles/tile-activity/backend/datapusher.js b/jive-sdk-service/generator/styles/tile-activity/backend/datapusher.js
index 3d0cc25..5c54a46 100644
--- a/jive-sdk-service/generator/styles/tile-activity/backend/datapusher.js
+++ b/jive-sdk-service/generator/styles/tile-activity/backend/datapusher.js
@@ -55,6 +55,7 @@ exports.task = function() {
'key':'count'
}).then(function(count) {
count = count.length > 0 ? count[0].count : parseInt(instance.config.startSequence, 10);
+ count = count || 0;
store.save('exampleStore', 'count', {
'key':'count',
'count':count+1
diff --git a/jive-sdk-service/lib/extension/extension.js b/jive-sdk-service/lib/extension/extension.js
index 7182b58..c43d7e8 100644
--- a/jive-sdk-service/lib/extension/extension.js
+++ b/jive-sdk-service/lib/extension/extension.js
@@ -232,9 +232,9 @@ function fillExtensionMetadata(extensionInfo, definitions, packageApps, cartridg
"name": name,
"description": description,
"minimum_version": extensionInfo['minJiveVersion'] || defaultMinimumVersion,
- "icon_16": "extension-16.png",
- "icon_48": "extension-48.png",
- "icon_128": "extension-128.png",
+ "icon_16": extensionInfo['icon16'] || "extension-16.png",
+ "icon_48": extensionInfo['icon48'] || "extension-48.png",
+ "icon_128": extensionInfo['icon128'] || "extension-128.png",
"released_on": extensionInfo['releasedOn'] || "2013-03-08T19:11:11.234Z",
"register_url": extensionInfo['registerURL'] || "%serviceURL%/jive/oauth/register",
"unregister_url": extensionInfo['unregisterURL'] || "%serviceURL%/jive/oauth/unregister",
diff --git a/jive-sdk-service/lib/service.js b/jive-sdk-service/lib/service.js
index 791aee4..3f88164 100644
--- a/jive-sdk-service/lib/service.js
+++ b/jive-sdk-service/lib/service.js
@@ -629,7 +629,7 @@ exports.getExpandedTileDefinitions = function(all) {
processedTile['updated'] = "2013-02-28T15:12:16.768-0800";
}
if ( processedTile['action'] ) {
- if ( processedTile['action'].indexOf('http') != 0 ) {
+ if ( processedTile['action'].indexOf('http') != 0 && processedTile['action'].indexOf('%serviceURL%') === -1) {
// assume its relative to host then
processedTile['action'] = host + ( processedTile['action'].indexOf('/') == 0 ? "" : "/" ) + processedTile['action'];
}
@@ -637,7 +637,7 @@ exports.getExpandedTileDefinitions = function(all) {
if ( !processedTile['config'] ) {
processedTile['config'] = host + '/' + processedTile['definitionDirName'] + '/configure';
} else {
- if ( processedTile['config'].indexOf('http') != 0 ) {
+ if ( processedTile['config'].indexOf('http') != 0 && processedTile['config'].indexOf('%serviceURL%') === -1) {
// assume its relative to host then
processedTile['config'] = host + ( processedTile['config'].indexOf('/') == 0 ? "" : "/" ) + processedTile['config'];
}
@@ -645,7 +645,7 @@ exports.getExpandedTileDefinitions = function(all) {
if ( !processedTile['unregister']) {
processedTile['unregister'] = host + '/unregister';
} else {
- if ( processedTile['unregister'].indexOf('http') != 0 ) {
+ if ( processedTile['unregister'].indexOf('http') != 0 && processedTile['unregister'].indexOf('%serviceURL%') === -1 ) {
// assume its relative to host then
processedTile['unregister'] = host + ( processedTile['unregister'].indexOf('/') == 0 ? "" : "/" ) + processedTile['unregister'];
}
@@ -654,15 +654,11 @@ exports.getExpandedTileDefinitions = function(all) {
if ( !processedTile['register'] ) {
processedTile['register'] = host + '/registration';
} else {
- if ( processedTile['register'].indexOf('http') != 0 ) {
+ if ( processedTile['register'].indexOf('http') != 0 && processedTile['register'].indexOf('%serviceURL%') === -1 ) {
// assume its relative to host then
processedTile['register'] = host + ( processedTile['register'].indexOf('/') == 0 ? "" : "/" ) + processedTile['register'];
}
}
- if ( processedTile['unregister'] && processedTile['unregister'].indexOf('http') != 0 ) {
- // assume its relative to host then
- processedTile['unregister'] = host + ( processedTile['unregister'].indexOf('/') == 0 ? "" : "/" ) + processedTile['unregister'];
- }
if ( !processedTile['client_id'] ) {
processedTile['client_id'] = conf.clientId;
}
diff --git a/package.json b/package.json
index 3dd9056..832dc10 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "jive-sdk",
"description": "Node.js framework for building purposeful places",
- "version": "0.1.145",
+ "version": "0.1.147",
"main": "jive-sdk-service/api.js",
"author": {
"name": "Jive Software",
@@ -21,8 +21,8 @@
"log4js": "0.6.3",
"xmlhttprequest": "~1.5.0",
"archiver" : "0.4.9",
- "http-proxy" : "*",
- "stream-array" : "*",
+ "http-proxy" : "1.5.3",
+ "stream-array" : "0.1.3",
"traverse" : "0.6.6",
"mv" : "~2.0.3"
},