You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by mf...@apache.org on 2011/07/15 16:03:33 UTC
svn commit: r1147159 - in /incubator/rave/trunk/rave-portal/src:
main/webapp/WEB-INF/views/home.jsp main/webapp/script/rave.js
main/webapp/script/rave_opensocial.js test/javascript/raveSpec.js
Author: mfranklin
Date: Fri Jul 15 14:03:31 2011
New Revision: 1147159
URL: http://svn.apache.org/viewvc?rev=1147159&view=rev
Log:
Refactored widget render process to map providers by type rather than widgets by type (Supports RAVE-53)
Modified:
incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp
incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js
incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_opensocial.js
incubator/rave/trunk/rave-portal/src/test/javascript/raveSpec.js
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp?rev=1147159&r1=1147158&r2=1147159&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp Fri Jul 15 14:03:31 2011
@@ -92,7 +92,8 @@
rave.setContext("<spring:url value="/app/" />");
rave.initGadgetUI(widgets);
rave.initProviders();
- rave.initWidgets(rave.createWidgetMap(widgets));
+ //rave.initWidgets(rave.createWidgetMap(widgets));
+ rave.initWidgets(widgets);
rave.initDragAndDrop();
});
</script>
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js?rev=1147159&r1=1147158&r2=1147159&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/script/rave.js Fri Jul 15 14:03:31 2011
@@ -17,7 +17,9 @@
* under the License.
*/
var rave = rave || (function() {
- var providerList = [];
+ var WIDGET_PROVIDER_ERROR = "This widget type is currently unsupported. Check with your administrator and be sure the correct provider is registered.";
+
+ var providerMap = {};
var context = "";
/**
@@ -131,22 +133,30 @@ var rave = rave || (function() {
//Providers register themselves when loaded, so
//JavaScript library importing order is important.
//See home.jsp for example.
- for (var i = 0; i < providerList.length; i++) {
- providerList[i].init();
+ for (var key in providerMap) {
+ providerMap[key].init();
}
}
function initializeWidgets(widgets) {
//Initialize the widgets for supported providers
- for (var i = 0; i < providerList.length; i++) {
- var provider = providerList[i];
- provider.initWidgets(widgets[provider.TYPE]);
+ for(var i=0; i<widgets.length; i++) {
+ initializeWidget(widgets[i]);
+ }
+ }
+
+ function initializeWidget(widget) {
+ var provider = providerMap[widget.type];
+ if (typeof provider == "undefined") {
+ renderErrorWidget(widget.regionWidgetId, WIDGET_PROVIDER_ERROR);
+ } else {
+ provider.initWidget(widget);
}
}
function addProviderToList(provider) {
if (provider.hasOwnProperty("init")) {
- providerList.push(provider);
+ providerMap[provider.TYPE] = provider;
} else {
throw "Attempted to register invalid provider";
}
@@ -173,6 +183,10 @@ var rave = rave || (function() {
return tokens.length > 2 && tokens[0] == "widget" || tokens[0] == "region" ? tokens[1] : null;
}
+ function renderErrorWidget(id, message) {
+ $("#widget-" + id + "-body").html(message);
+ }
+
function updateContext(contextPath) {
context = contextPath;
}
@@ -231,6 +245,10 @@ var rave = rave || (function() {
/**
* Initializes the given set of widgets
* @param widgets a map of widgets by type
+ *
+ * NOTE: widget object must have at a minimum the following properties:
+ * type,
+ * regionWidgetId
*/
initWidgets : initializeWidgets,
@@ -260,7 +278,7 @@ var rave = rave || (function() {
getObjectIdFromDomId : extractObjectIdFromElementId,
/**
- * Registers a new provider with Rave. All providers MUST have init and initWidgets functions as well as a
+ * Registers a new provider with Rave. All providers MUST have init and initWidget functions as well as a
* TYPE property exposed in its public API
*
* @param provider a valid Rave widget provider
@@ -268,6 +286,14 @@ var rave = rave || (function() {
registerProvider : addProviderToList,
/**
+ * Renders an error in place of the gadget
+ *
+ * @param id the RegionWidgetId of the widget to render in error mode
+ * @param message The message to display to the suer
+ */
+ errorWidget: renderErrorWidget,
+
+ /**
* Sets the context path for the Rave web application
*
* @param contextPath the context path of the rave webapp
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_opensocial.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_opensocial.js?rev=1147159&r1=1147158&r2=1147159&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_opensocial.js (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_opensocial.js Fri Jul 15 14:03:31 2011
@@ -67,58 +67,62 @@ rave.opensocial = rave.opensocial || (fu
}
/**
- * Creates and renders the list of gadgets
+ * Renders a gadget on the page
*
- * @param gadgets list of gadget objects that are to be rendered by the container
+ * @param gadget the gadget object to be rendered by the container
*/
- function createGadgetInstances(gadgets) {
+ function createGadgetInstance(gadget) {
- //break out of the function if there are no OpenSocial gadgets
- if(!gadgets || gadgets.length == 0) return;
+ var gadgetMetadata = gadget.metadata;
+ var validationResult = validateMetadata(gadgetMetadata);
+ if (validationResult.valid) {
+ //TODO: Submit a patch to Shindig common container to expose the backing service or add a method to push cached items into the container config
+ container.service_.addGadgetMetadatas(gadgetMetadata[0].result, null);
+
+ var renderParams = {};
+ renderParams[osapi.container.RenderParam.VIEW] = "home";
+ renderParams[osapi.container.RenderParam.WIDTH] = 250;
+ renderParams[osapi.container.RenderParam.HEIGHT] = 250;
+ renderParams[osapi.container.RenderParam.USER_PREFS] = getCompleteUserPrefSet(gadget.userPrefs, gadgetMetadata[0].result[gadget.widgetUrl].userPrefs);
+ var widgetBodyElement = document.getElementById(["widget-", gadget.regionWidgetId, "-body"].join(""));
+ var gadgetSite = container.newGadgetSite(widgetBodyElement);
+ container.navigateGadget(gadgetSite, gadget.widgetUrl, {}, renderParams);
-
- //Create a list of gadget URLs from the gadget objects
- var gadgetUrls = [];
- for(var i = 0; i < gadgets.length; i++) {
- gadgetUrls.push(gadgets[i].widgetUrl);
+ } else {
+ rave.errorWidget(gadget.regionWidgetId, "Unable to render OpenSocial Gadget: <br /><br />" + validationResult.error);
}
- /**
- * Tell the common container to pre-load the metadata for all the widgets we're going to ask it to render. If we
- * don't do this then when we call navigateGadget for each regionWidget the common container will fetch the metadata
- * for each one at a time. We also pass a callback function which will take the metadata retrieved from the preload
- * so we can get all the default values for userPrefs and pass them along with our navigateGadget call.
- *
- * TODO: Prime the common container metadata cache with data we pull from our own persistent store so that we dont have
- * to have common container fetch metadata on every page render. See osapi.container.Container.prototype.preloadFromConfig_
- * function which gets called from the osapi.container.Container constructor to get an idea of how this might be done.
- *
- * TODO: Use real userPrefs that we pull from our persistent store instead of the default values pulled from common
- * containers metadata call.
- *
- * TODO: Get real moduleId's based on the regionWidget.id into the iframe URL. Right now common container uses an
- * internal counter for the mid parameter value with no external way to set it.
- */
- container.preloadGadgets(gadgetUrls, function(response) {
- for (var i = 0; i < gadgets.length; i++) {
- var gadget = gadgets[i];
- var gadgetMetadata = response[gadget.widgetUrl];
-
- for (var userPref in gadgetMetadata.userPrefs) {
- userPref = gadgetMetadata.userPrefs[userPref];
- gadget.userPrefs[userPref.name] = userPref.defaultValue;
- }
+ }
- var renderParams = {};
- renderParams[osapi.container.RenderParam.VIEW] = "home";
- renderParams[osapi.container.RenderParam.WIDTH] = 250;
- renderParams[osapi.container.RenderParam.HEIGHT] = 250;
- renderParams[osapi.container.RenderParam.USER_PREFS] = gadget.userPrefs;
- var widgetBodyElement = document.getElementById(["widget-", gadget.regionWidgetId, "-body"].join(""));
- var gadgetSite = container.newGadgetSite(widgetBodyElement);
- container.navigateGadget(gadgetSite, gadget.widgetUrl, {}, renderParams);
+ /**
+ * validates the metadata for the current gadget
+ * @param metadatas the list of metadata objects to validate
+ */
+ function validateMetadata(metadatas) {
+ for(var i = 0; i < metadatas.length; i++) {
+ var result = metadatas[i].result;
+ for(var url in result) {
+ if(typeof result[url].error != "undefined") {
+ return {valid:false, error:result[url].error.message};
+ }
}
- });
+ }
+ return {valid:true};
+ }
+
+ /**
+ * Combines the default user pref list from the metadata with those set by the user
+ * @param setPrefs preferences already set by the user
+ * @param metadataPrefs list of all available metadata objects
+ */
+ function getCompleteUserPrefSet(setPrefs, metadataPrefs) {
+ var combined = {};
+ for (var key in metadataPrefs) {
+ var metaPref = metadataPrefs[key];
+ var userPref = setPrefs[metaPref.name];
+ combined[metaPref.name] = typeof userPref == "undefined" ? metaPref.defaultValue : userPref;
+ }
+ return combined;
}
/*
@@ -191,10 +195,10 @@ rave.opensocial = rave.opensocial || (fu
*/
container: getContainer,
/**
- * Instantiates and renders the given gadgets list
- * @param a list of gadgets to render
+ * Instantiates and renders the given gadget
+ * @param a gadget to render
*/
- initWidgets: createGadgetInstances,
+ initWidget: createGadgetInstance,
/**
* Resets the current OpenSocial container
Modified: incubator/rave/trunk/rave-portal/src/test/javascript/raveSpec.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/javascript/raveSpec.js?rev=1147159&r1=1147158&r2=1147159&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/javascript/raveSpec.js (original)
+++ incubator/rave/trunk/rave-portal/src/test/javascript/raveSpec.js Fri Jul 15 14:03:31 2011
@@ -21,21 +21,19 @@ describe("Rave", function() {
function getMockProvider(type) {
return (function() {
var called = false;
- var widgetsCalled = false;
+ var callCount = 0;
return {
TYPE : type,
init : function() {
called = true;
},
- initWidgets: function(widgets) {
- for (var i = 0; i < widgets.length; i++) {
- expect(widgets[i].type).toEqual(type);
- }
- widgetsCalled = true;
+ initWidget: function(widget) {
+ expect(widget.type).toEqual(type);
+ callCount++;
},
- initWidgetsWasCalled : function() {
- return widgetsCalled;
+ initWidgetsWasCalled : function(expected) {
+ return expected == callCount;
},
initWasCalled : function() {
return called;
@@ -68,24 +66,66 @@ describe("Rave", function() {
});
describe("initWidgets", function() {
+
+ //Creates a simple mock jquery object that records one call and returns the result of the call
+ function createMockJQuery() {
+ var html;
+ var expression;
+ $ = function(expr) {
+
+ if (typeof expr != "undefined") {
+ expression = expr;
+ }
+
+ return {
+ expression : function () {
+ return expression;
+ },
+ html : function (txt) {
+ if (typeof txt == "string") {
+ html = txt;
+ return $;
+ } else {
+ return html;
+ }
+ }
+ }
+ };
+ }
+
it("calls the appropriate providers", function() {
- var widgetMap = {
- "FOO" : [
+ var widgetList = [
{type:"FOO"},
- {type:"FOO"}
- ],
- "BAR" : [
{type:"BAR"},
+ {type:"FOO"},
{type:"BAR"}
- ]
- };
+ ];
+ var provider1 = getMockProvider("FOO");
+ var provider2 = getMockProvider("BAR");
+ rave.registerProvider(provider1);
+ rave.registerProvider(provider2);
+ rave.initWidgets(widgetList);
+ expect(provider1.initWidgetsWasCalled(2)).toBeTruthy();
+ expect(provider2.initWidgetsWasCalled(2)).toBeTruthy();
+ });
+ it("Renders an error gadget when invalid widget is provided", function(){
+ var widgetList = [
+ {type:"FOO", regionWidgetId:20},
+ {type:"BAR", regionWidgetId:21},
+ {type:"FOO", regionWidgetId:22},
+ {type:"BAR", regionWidgetId:23},
+ {type:"NONE", regionWidgetId:43}
+ ];
+ createMockJQuery();
var provider1 = getMockProvider("FOO");
var provider2 = getMockProvider("BAR");
rave.registerProvider(provider1);
rave.registerProvider(provider2);
- rave.initWidgets(widgetMap);
- expect(provider1.initWidgetsWasCalled()).toBeTruthy();
- expect(provider2.initWidgetsWasCalled()).toBeTruthy();
+ rave.initWidgets(widgetList);
+ expect($().expression()).toEqual("#widget-43-body");
+ expect($().html()).toEqual("This widget type is currently unsupported. Check with your administrator and be sure the correct provider is registered.");
+ expect(provider1.initWidgetsWasCalled(2)).toBeTruthy();
+ expect(provider2.initWidgetsWasCalled(2)).toBeTruthy();
});
});