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();
         });
     });