You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by mh...@apache.org on 2010/09/13 21:58:46 UTC

svn commit: r996670 - in /shindig/trunk: features/src/main/javascript/features/container/ java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/

Author: mhermanto
Date: Mon Sep 13 19:58:45 2010
New Revision: 996670

URL: http://svn.apache.org/viewvc?rev=996670&view=rev
Log:
Common container updates --
- Reduce the response size, by filtering the fields needed.
- Prioritize initial iframe size to: requested size, view-specified size, moduleprefs-specified size, default.
- Allow disabling of security token update by setting it to -1.
- gadgets.rpc.call to update_security_token now only work if there is 1+ gadgets receiving it. This avoids warning of rpc service not found.
- Make most (not all yet) JSON keys constants.

http://codereview.appspot.com/2130041/

Added:
    shindig/trunk/features/src/main/javascript/features/container/constant.js
Modified:
    shindig/trunk/features/src/main/javascript/features/container/container.js
    shindig/trunk/features/src/main/javascript/features/container/feature.xml
    shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js
    shindig/trunk/features/src/main/javascript/features/container/gadget_site.js
    shindig/trunk/features/src/main/javascript/features/container/service.js
    shindig/trunk/features/src/main/javascript/features/container/util.js
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java

Added: shindig/trunk/features/src/main/javascript/features/container/constant.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/constant.js?rev=996670&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/constant.js (added)
+++ shindig/trunk/features/src/main/javascript/features/container/constant.js Mon Sep 13 19:58:45 2010
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+
+/**
+ * @fileoverview Constants used throughout common container.
+ */
+
+
+/**
+ * Set up namespace.
+ * @type {Object}
+ */
+shindig.container = {};
+
+
+/**
+ * Constants to key into gadget metadata response JSON.
+ * @enum {string}
+ */
+shindig.container.MetadataResponse = {};
+shindig.container.MetadataResponse.IFRAME_URL = 'iframeUrl';
+shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH = 'needsTokenRefresh';
+shindig.container.MetadataResponse.VIEWS = 'views';
+shindig.container.MetadataResponse.FEATURES = 'features';
+shindig.container.MetadataResponse.HEIGHT = 'height';
+shindig.container.MetadataResponse.MODULE_PREFS = 'modulePrefs';
+shindig.container.MetadataResponse.PREFERRED_HEIGHT = 'preferredHeight';
+shindig.container.MetadataResponse.PREFERRED_WIDTH = 'preferredWidth';
+shindig.container.MetadataResponse.WIDTH = 'width';
+
+
+/**
+ * Constants to key into gadget token response JSON.
+ * @enum {string}
+ */
+shindig.container.TokenResponse = {};
+shindig.container.TokenResponse.TOKEN = 'token';
+
+
+/**
+ * Constants to key into request renderParam JSON.
+ * @enum {string}
+ */
+shindig.container.RenderParam = {};
+shindig.container.RenderParam.CLASS = 'class';
+shindig.container.RenderParam.DEBUG = 'debug';
+shindig.container.RenderParam.HEIGHT = 'height';
+shindig.container.RenderParam.NO_CACHE = 'nocache';
+shindig.container.RenderParam.TEST_MODE = 'testmode';
+shindig.container.RenderParam.USER_PREFS = 'userPrefs';
+shindig.container.RenderParam.VIEW = 'view';
+shindig.container.RenderParam.WIDTH = 'width';
+
+/**
+ * Constants to key into request viewParam JSON.
+ * @enum {string}
+ */
+shindig.container.ViewParam = {};
+shindig.container.ViewParam.VIEW = 'view';

Modified: shindig/trunk/features/src/main/javascript/features/container/container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/container.js?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/container.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/container.js Mon Sep 13 19:58:45 2010
@@ -138,12 +138,12 @@ shindig.container.Container.prototype.ge
  *
  * @param {shindig.container.GadgetSite} site destination gadget to navigate to.
  * @param {string} gadgetUrl The URI of the gadget.
- * @param {Object} gadgetParams view params for the gadget.
+ * @param {Object} viewParams view params for the gadget.
  * @param {Object} renderParams render parameters, including the view.
  * @param {function(Object)=} opt_callback Callback after gadget is loaded.
  */
 shindig.container.Container.prototype.navigateGadget = function(
-    site, gadgetUrl, gadgetParams, renderParams, opt_callback) {
+    site, gadgetUrl, viewParams, renderParams, opt_callback) {
   var callback = opt_callback || function() {};
   if (this.renderDebug_) {
     renderParams['nocache'] = true;
@@ -155,14 +155,14 @@ shindig.container.Container.prototype.na
 
   var self = this;
   // TODO: Lifecycle, add ability for current gadget to cancel nav.
-  site.navigateTo(gadgetUrl, gadgetParams, renderParams, function(response) {
+  site.navigateTo(gadgetUrl, viewParams, renderParams, function(gadgetInfo) {
     // TODO: Navigate to error screen on primary gadget load failure
     // TODO: Should display error without doing a standard navigate.
     // TODO: Bad if the error gadget fails to load.
-    if (!response.error) {
+    if (gadgetInfo[shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) {
       self.scheduleRefreshTokens_();
     }
-    callback(response);
+    callback(gadgetInfo);
   });
 };
 
@@ -195,17 +195,17 @@ shindig.container.Container.prototype.pr
  * @param {Array} gadgetUrls gadgets URIs to preload.
  */
 shindig.container.Container.prototype.preloadGadgets = function(gadgetUrls) {
-  var request = {
-      'container' : window.__CONTAINER,
-      'ids' : gadgetUrls
-  };
+  var request = shindig.container.util.newMetadataRequest(gadgetUrls);
   var self = this;
   this.service_.getGadgetMetadata(request, function(response) {
     if (!response.error) {
       for (var id in response) {
         self.addPreloadedGadgetUrl_(id);
+        if (response[id][shindig.container.MetadatResponse.NEEDS_TOKEN_REFRESH]) {
+          // Safe to re-schedule many times.
+          self.scheduleRefreshTokens_();
+        }
       }
-      self.scheduleRefreshTokens_();
     }
   });
 };
@@ -218,10 +218,7 @@ shindig.container.Container.prototype.pr
  */
 shindig.container.Container.prototype.getGadgetMetadata = function(
     gadgetUrl, callback) {
-  var request = {
-      'container' : window.__CONTAINER,
-      'ids' : [ gadgetUrl ]
-  };
+  var request = shindig.container.util.newMetadataRequest([gadgetUrl]);
   this.service_.getGadgetMetadata(request, callback);
 };
 
@@ -293,7 +290,7 @@ shindig.container.Container.prototype.sc
   // token in all preloaded- and navigated-to- gadgets. This should be obtained
   // from the server. For now, constant on 50% of long-lived tokens (1 hour),
   // which is 30 minutes.
-  if (!this.tokenRefreshTimer_) {
+  if (this.isRefreshTokensEnabled_() && !this.tokenRefreshTimer_) {
     var self = this;
     this.tokenRefreshTimer_ = window.setInterval(function() {
         self.refreshTokens_();
@@ -318,6 +315,19 @@ shindig.container.Container.prototype.un
 
 
 /**
+ * Provides a manual override to disable token refresh to avoid gadgets.rpc
+ * warning of service not found. We can do better to detect if token refresh is
+ * even necessary, by inspecting the gadget transitively depend on
+ * feature=security-token.
+ * @return {Boolean} if token refresh interval is of valid value.
+ * @private
+ */
+shindig.container.Container.prototype.isRefreshTokensEnabled_ = function() {
+  return this.tokenRefreshInterval_ > 0;
+};
+
+
+/**
  * Register standard RPC services
  * @private
  */
@@ -351,14 +361,23 @@ shindig.container.Container.prototype.ad
  */
 shindig.container.Container.prototype.getTokenRefreshableGadgetUrls_ =
     function() {
-  // Uses a JSON to ensure uniqueness. Collect all preloaded gadget URLs.
-  var result = shindig.container.util.mergeJsons({}, this.preloadedGadgetUrls_);
+  var result = {};
+
+  // Collect preloaded gadget urls.
+  for (var url in this.preloadedGadgetUrls_) {
+    var metadata = this.service_.getCachedGadgetMetadata(url);
+    if (metadata[shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) {
+      result[url] = null;
+    }
+  }
 
-  // Collect all current gadget URLs.
+  // Collect active gadget urls.
   for (var siteIndex in this.sites_) {
-    var holder = this.sites_[siteIndex].getActiveGadget();
-    if (holder) {
-      result[holder.getUrl()] = null;
+    var holder = this.sites_[siteIndex].getActiveGadgetHolder();
+    var url = holder.getUrl();
+    var metadata = this.service_.getCachedGadgetMetadata(url);
+    if (metadata[shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) {
+      result[url] = null;
     }
   }
 
@@ -366,6 +385,7 @@ shindig.container.Container.prototype.ge
 };
 
 
+
 /**
  * Refresh security tokens immediately. This will fetch gadget metadata, along
  * with its token and have the token cache updated.
@@ -373,23 +393,20 @@ shindig.container.Container.prototype.ge
  */
 shindig.container.Container.prototype.refreshTokens_ = function() {
   var ids = this.getTokenRefreshableGadgetUrls_();
-  var request = {
-    'container' : window.__CONTAINER,
-    'ids' : ids
-  };
+  var request = shindig.container.util.newTokenRequest(ids);
 
   var self = this;
   this.service_.getGadgetToken(request, function(response) {
     if (!response.error) {
-      // Update current (visible) gadgets with new tokens (already stored in
-      // cache). Do not need to update pre-loaded gadgets, since new tokens will
-      // take effect when they are navigated to.
+      // Update active token-requiring gadgets with new tokens. Do not need to
+      // update pre-loaded gadgets, since new tokens will take effect when they
+      // are navigated to, from cache.
       for (var key in self.sites_) {
-        var holder = self.sites_[key].getActiveGadget();
-        if (holder) {
-          var token = response[holder.getUrl()]['token'];
+        var holder = self.sites_[key].getActiveGadgetHolder();
+        var gadgetInfo = self.service_.getCachedGadgetMetadata(holder.getUrl());
+        if (gadgetInfo[shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) {
           gadgets.rpc.call(holder.getIframeId(), 'update_security_token', null,
-              token);
+              response[holder.getUrl()][shindig.container.TokenResponse.TOKEN]);
         }
       }
     }

Modified: shindig/trunk/features/src/main/javascript/features/container/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/feature.xml?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/feature.xml (original)
+++ shindig/trunk/features/src/main/javascript/features/container/feature.xml Mon Sep 13 19:58:45 2010
@@ -27,6 +27,7 @@ under the License.
   <dependency>osapi</dependency>
   <dependency>rpc</dependency>
   <container>
+    <script src="constant.js"/>
     <script src="util.js"/>
     <script src="service.js"/>
     <script src="gadget_holder.js"/>

Modified: shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js Mon Sep 13 19:58:45 2010
@@ -54,14 +54,7 @@ shindig.container.GadgetHolder = functio
    * @type {Object?}
    * @private
    */
-  this.gadgetParams_ = null;
-
-  /**
-   * Whether there are any view parameters.
-   * @type {boolean}
-   * @private
-   */
-  this.hasGadgetParams_ = false;
+  this.viewParams_ = null;
 
   /**
    * Gadget rendering parameters
@@ -78,13 +71,6 @@ shindig.container.GadgetHolder = functio
   this.iframeId_ = null;
 
   /**
-   * Name of current view being rendered.
-   * @type {string?}
-   * @private
-   */
-  this.view_ = null;
-
-  /**
    * A dynamically set social/security token.
    * Social tokens are sent with original view URLs but may need
    * to be refreshed for long lived gadgets.
@@ -148,7 +134,7 @@ shindig.container.GadgetHolder.prototype
  * @return {string|null} The view of current gadget.
  */
 shindig.container.GadgetHolder.prototype.getView = function() {
-  return this.view_;
+  return this.renderParams_[shindig.container.RenderParam.VIEW];
 };
 
 
@@ -173,24 +159,18 @@ shindig.container.GadgetHolder.prototype
 /**
  * Render a gadget into the element.
  * @param {Object} gadgetInfo the JSON gadget description.
- * @param {Object} gadgetParams View parameters for the gadget.
+ * @param {Object} viewParams View parameters for the gadget.
  * @param {Object} renderParams Render parameters for the gadget, including:
  *     view, width, height.
  */
 shindig.container.GadgetHolder.prototype.render = function(
-    gadgetInfo, gadgetParams, renderParams) {
+    gadgetInfo, viewParams, renderParams) {
   this.iframeId_ = shindig.container.GadgetHolder.IFRAME_ID_PREFIX_
       + this.siteId_;
   this.gadgetInfo_ = gadgetInfo;
-  this.gadgetParams_ = gadgetParams;
-  this.hasGadgetParams_ = false;
-  for (var key in this.gadgetParams_) {
-    this.hasGadgetParams_ = true;
-    break;
-  }
+  this.viewParams_ = viewParams;
   this.renderParams_ = renderParams;
-  this.view_ = renderParams['view'];
-  if (!this.gadgetInfo_['views'][this.view_]) {
+  if (!this.gadgetInfo_[shindig.container.MetadataResponse.VIEWS][this.getView()]) {
     throw 'View ' + this.view_ + ' unsupported in ' + this.gadgetInfo_['url'];
   }
 
@@ -198,7 +178,8 @@ shindig.container.GadgetHolder.prototype
 
   // Set up RPC channel. RPC relay url is on gmodules, relative to base of the
   // container. Assumes container has set up forwarding to gmodules at /gadgets.
-  var iframeUri = shindig.uri(this.gadgetInfo_['iframeUrl']);
+  var iframeUri = shindig.uri(
+      this.gadgetInfo_[shindig.container.MetadataResponse.IFRAME_URL]);
   var relayUri = shindig.uri()
       .setSchema(iframeUri.getSchema())
       .setAuthority(iframeUri.getAuthority())
@@ -237,9 +218,9 @@ shindig.container.GadgetHolder.prototype
       'frameborder': '0',
       'vspace': '0',
       'hspace': '0',
-      'class': this.renderParams_['class'],
-      'height': this.renderParams_['height'],
-      'width': this.renderParams_['width']
+      'class': this.renderParams_[shindig.container.RenderParam.CLASS],
+      'height': this.renderParams_[shindig.container.RenderParam.HEIGHT],
+      'width': this.renderParams_[shindig.container.RenderParam.WIDTH]
   };
 
   // Do not use DOM API (createElement(), setAttribute()), since it is slower,
@@ -265,11 +246,11 @@ shindig.container.GadgetHolder.prototype
  * @private
  */
 shindig.container.GadgetHolder.prototype.getIframeUrl_ = function() {
-  var uri = shindig.uri(this.gadgetInfo_['iframeUrl']);
-  uri.setQP('debug', this.renderParams_['debug'] ? '1' : '0');
-  uri.setQP('nocache', this.renderParams_['nocache'] ? '1' : '0');
-  uri.setQP('testmode', this.renderParams_['testmode'] ? '1' : '0');
-  uri.setQP('view', this.view_);
+  var uri = shindig.uri(this.gadgetInfo_[shindig.container.MetadataResponse.IFRAME_URL]);
+  uri.setQP('debug', this.renderParams_[shindig.container.RenderParam.DEBUG] ? '1' : '0');
+  uri.setQP('nocache', this.renderParams_[shindig.container.RenderParam.NO_CACHE] ? '1' : '0');
+  uri.setQP('testmode', this.renderParams_[shindig.container.RenderParam.TEST_MODE] ? '1' : '0');
+  uri.setQP('view', this.getView());
   this.updateUserPrefParams_(uri);
 
   // TODO: Share this base container logic
@@ -284,8 +265,8 @@ shindig.container.GadgetHolder.prototype
   
   uri.setFP('mid', String(this.siteId_));
 
-  if (this.hasGadgetParams_) {
-    var gadgetParamText = gadgets.json.stringify(this.gadgetParams_);
+  if (this.hasViewParams_()) {
+    var gadgetParamText = gadgets.json.stringify(this.viewParams_);
     uri.setFP('view-params', gadgetParamText);
   }
 
@@ -303,7 +284,7 @@ shindig.container.GadgetHolder.prototype
  * @private
  */
 shindig.container.GadgetHolder.prototype.updateUserPrefParams_ = function(uri) {
-  var userPrefs = this.renderParams_['userPrefs'];
+  var userPrefs = this.renderParams_[shindig.container.RenderParam.USER_PREFS];
   if (userPrefs) {
     for (var up in userPrefs) {
       var upKey = 'up_' + up;
@@ -315,3 +296,16 @@ shindig.container.GadgetHolder.prototype
     }
   }
 };
+
+
+/**
+ * Return true if this has view parameters.
+ * @private
+ * @return {Boolean}
+ */
+shindig.container.GadgetHolder.prototype.hasViewParams_ = function() {
+  for (var key in this.viewParams_) {
+    return true;
+  }
+  return false;
+};

Modified: shindig/trunk/features/src/main/javascript/features/container/gadget_site.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/gadget_site.js?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/gadget_site.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/gadget_site.js Mon Sep 13 19:58:45 2010
@@ -43,7 +43,7 @@ shindig.container.GadgetSite = function(
    * @type {Element}
    * @private
    */
-  this.curGadgetEl_ = gadgetEl;
+  this.currentGadgetEl_ = gadgetEl;
 
   /**
    * Element holding the loading gadget for 2x buffering.
@@ -71,14 +71,14 @@ shindig.container.GadgetSite = function(
    * @type {shindig.container.GadgetHolder?}
    * @private
    */
-  this.curGadget_ = null;
+  this.currentGadgetHolder_ = null;
 
   /**
    * Information about the currently loading gadget.
    * @type {shindig.container.GadgetHolder?}
    * @private
    */
-  this.loadingGadget_ = null;
+  this.loadingGadgetHolder_ = null;
 
   this.onConstructed();
 };
@@ -97,9 +97,9 @@ shindig.container.GadgetSite.prototype.o
  * @return {shindig.container.GadgetSite} This instance.
  */
 shindig.container.GadgetSite.prototype.setHeight = function(value) {
-  var activeGadget = this.getActiveGadget();
-  if (activeGadget) {
-    var iframeEl = activeGadget.getIframeElement();
+  var holder = this.getActiveGadgetHolder();
+  if (holder) {
+    var iframeEl = holder.getIframeElement();
     if (iframeEl) {
       iframeEl.style.height = value + 'px';
     }
@@ -114,9 +114,9 @@ shindig.container.GadgetSite.prototype.s
  * @return {shindig.container.GadgetSite} This instance.
  */
 shindig.container.GadgetSite.prototype.setWidth = function(value) {
-  var activeGadget = this.getActiveGadget();
-  if (activeGadget) {
-    var iframeEl = activeGadget.getIframeElement();
+  var holder = this.getActiveGadgetHolder();
+  if (holder) {
+    var iframeEl = holder.getIframeElement();
     if (iframeEl) {
       iframeEl.style.width = value + 'px';
     }
@@ -148,8 +148,8 @@ shindig.container.GadgetSite.prototype.g
  * loading, or the currently visible gadget.
  * @return {shindig.container.GadgetHolder} The gadget holder.
  */
-shindig.container.GadgetSite.prototype.getActiveGadget = function() {
-  return this.loadingGadget_ || this.curGadget_;
+shindig.container.GadgetSite.prototype.getActiveGadgetHolder = function() {
+  return this.loadingGadgetHolder_ || this.currentGadgetHolder_;
 };
 
 
@@ -161,8 +161,9 @@ shindig.container.GadgetSite.prototype.g
  * @return {Object} JSON representing the feature.
  */
 shindig.container.GadgetSite.prototype.getFeature = function(name, opt_gadgetInfo) {
-  var gadgetInfo = opt_gadgetInfo || this.getActiveGadget().getGadgetInfo();
-  return gadgetInfo['features'] && gadgetInfo['features'][name];
+  var gadgetInfo = opt_gadgetInfo || this.getActiveGadgetHolder().getGadgetInfo();
+  return gadgetInfo[shindig.container.MetadataResponse.FEATURES] &&
+      gadgetInfo[shindig.container.MetadataResponse.FEATURES][name];
 };
 
 
@@ -172,11 +173,11 @@ shindig.container.GadgetSite.prototype.g
  * @return {shindig.container.GadgetHolder?} The gadget. Null, if not exist.
  */
 shindig.container.GadgetSite.prototype.getGadgetHolder = function(id) {
-  if (this.curGadget_ && this.curGadget_.getIframeId() == id) {
-    return this.curGadget_;
+  if (this.currentGadgetHolder_ && this.currentGadgetHolder_.getIframeId() == id) {
+    return this.currentGadgetHolder_;
   }
-  if (this.loadingGadget_ && this.loadingGadget_.getIframeId() == id) {
-    return this.loadingGadget_;
+  if (this.loadingGadgetHolder_ && this.loadingGadgetHolder_.getIframeId() == id) {
+    return this.loadingGadgetHolder_;
   }
   return null;
 };
@@ -193,33 +194,30 @@ shindig.container.GadgetSite.prototype.g
 /**
  * Render a gadget in the site, by URI of the gadget XML.
  * @param {string} gadgetUrl The absolute URL to gadget.
- * @param {Object} gadgetParams View parameters for the gadget.
+ * @param {Object} viewParams View parameters for the gadget.
  * @param {Object} renderParams. Render parameters for the gadget, including:
  *     view, width, height.
  * @param {function(Object)=} opt_callback Function called with gadget info after
  *     navigation has occurred.
  */
 shindig.container.GadgetSite.prototype.navigateTo = function(
-    gadgetUrl, gadgetParams, renderParams, opt_callback) {
+    gadgetUrl, viewParams, renderParams, opt_callback) {
   var callback = opt_callback || function() {};
   
   // If metadata has been loaded/cached.
   var gadgetInfo = this.service_.getCachedGadgetMetadata(gadgetUrl);
   if (gadgetInfo) {
-    this.render(gadgetInfo, gadgetParams, renderParams);
+    this.render(gadgetInfo, viewParams, renderParams);
     callback(gadgetInfo);
 
   // Otherwise, fetch gadget metadata.
   } else {
-    var request = {
-      'container': window.__CONTAINER,
-      'ids': [ gadgetUrl ]
-    };
+    var request = shindig.container.util.newMetadataRequest([gadgetUrl]);
     var self = this;
     this.service_.getGadgetMetadata(request, function(response) {
       if (!response.error) {
         var gadgetInfo = response[gadgetUrl];
-        self.render(gadgetInfo, gadgetParams, renderParams);
+        self.render(gadgetInfo, viewParams, renderParams);
         callback(gadgetInfo);
       } else {
         callback(response);
@@ -232,26 +230,28 @@ shindig.container.GadgetSite.prototype.n
 /**
  * Render a gadget in this site, using a JSON gadget description.
  * @param {Object} gadgetInfo the JSON gadget description.
- * @param {Object} gadgetParams View parameters for the gadget.
+ * @param {Object} viewParams View parameters for the gadget.
  * @param {Object} renderParams. Render parameters for the gadget, including:
  *     view, width, height.
  */
 shindig.container.GadgetSite.prototype.render = function(
-    gadgetInfo, gadgetParams, renderParams) {
-  var curUrl = this.curGadget_ ? this.curGadget_.getUrl() : null;
+    gadgetInfo, viewParams, renderParams) {
+  var curUrl = this.currentGadgetHolder_ ? this.currentGadgetHolder_.getUrl() : null;
 
   var previousView = null;
   if (curUrl == gadgetInfo['url']) {
-    previousView = this.curGadget_.getView();
+    previousView = this.currentGadgetHolder_.getView();
   }
 
   // Load into the double-buffer if there is one
-  var el = this.loadingGadgetEl_ || this.curGadgetEl_;
-  this.loadingGadget_ = new shindig.container.GadgetHolder(this.id_, el);
+  var el = this.loadingGadgetEl_ || this.currentGadgetEl_;
+  this.loadingGadgetHolder_ = new shindig.container.GadgetHolder(this.id_, el);
 
-  var view = renderParams['view'] || gadgetParams['view'] || previousView
+  var view = renderParams[shindig.container.RenderParam.VIEW]
+      || viewParams[shindig.container.ViewParam.VIEW]
+      || previousView
       || 'default';
-  var viewInfo = gadgetInfo['views'][view];
+  var viewInfo = gadgetInfo[shindig.container.MetadataResponse.VIEWS][view];
 
   var delayLoad = this.getFeature('loadstate', gadgetInfo) ||
       this.getFeature('shell', gadgetInfo);
@@ -263,17 +263,23 @@ shindig.container.GadgetSite.prototype.r
 
   // Delay load for now means we autosize.
   if (delayLoad) {
-    localRenderParams['height'] = '0';
+    localRenderParams[shindig.container.RenderParam.HEIGHT] = '0';
   }
-  localRenderParams['view'] = view;
-  localRenderParams['width'] = localRenderParams['width'] ||
-      viewInfo['preferredWidth'] || null;
-  localRenderParams['height'] = localRenderParams['height'] ||
-      viewInfo['preferredHeight'] || '150';
+  localRenderParams[shindig.container.RenderParam.VIEW] = view;
+  localRenderParams[shindig.container.RenderParam.HEIGHT]
+      = renderParams[shindig.container.RenderParam.HEIGHT]
+      || viewInfo[shindig.container.MetadataResponse.PREFERRED_HEIGHT]
+      || gadgetInfo[shindig.container.MetadataResponse.MODULE_PREFS][shindig.container.MetadataResponse.HEIGHT]
+      || String(shindig.container.GadgetSite.DEFAULT_HEIGHT_);
+  localRenderParams[shindig.container.RenderParam.WIDTH]
+      = renderParams[shindig.container.RenderParam.WIDTH]
+      || viewInfo[shindig.container.MetadataResponse.PREFERRED_WIDTH]
+      || gadgetInfo[shindig.container.MetadataResponse.MODULE_PREFS][shindig.container.MetadataResponse.WIDTH]
+      || String(shindig.container.GadgetSite.DEFAULT_WIDTH_);
 
   this.updateSecurityToken_(gadgetInfo, localRenderParams);
 
-  this.loadingGadget_.render(gadgetInfo, gadgetParams, localRenderParams);
+  this.loadingGadgetHolder_.render(gadgetInfo, viewParams, localRenderParams);
 
   this.loaded_ = false;
 
@@ -294,8 +300,9 @@ shindig.container.GadgetSite.prototype.r
  */
 shindig.container.GadgetSite.prototype.rpcCall = function(
     serviceName, callback, var_args) {
-  if (this.curGadget_) {
-    gadgets.rpc.call(this.curGadget_.getIframeId(), serviceName, callback, var_args);
+  if (this.currentGadgetHolder_) {
+    gadgets.rpc.call(this.currentGadgetHolder_.getIframeId(),
+        serviceName, callback, var_args);
   }
 };
 
@@ -311,8 +318,8 @@ shindig.container.GadgetSite.prototype.u
     = function(gadgetInfo, renderParams) {
   var tokenInfo = this.service_.getCachedGadgetToken(gadgetInfo['url']);
   if (tokenInfo) {
-    var token = tokenInfo['token'];
-    this.loadingGadget_.setSecurityToken(token);
+    var token = tokenInfo[shindig.container.TokenResponse.TOKEN];
+    this.loadingGadgetHolder_.setSecurityToken(token);
   }
 };
 
@@ -323,18 +330,17 @@ shindig.container.GadgetSite.prototype.u
  * for removal.
  */
 shindig.container.GadgetSite.prototype.close = function() {
-  // Only remove the element (iframe) created by this, not by the container.
-  if (this.loadingGadgetEl_) {
+  if (this.loadingGadgetEl_ && this.loadingGadgetEl_.firstChild) {
     this.loadingGadgetEl_.removeChild(this.loadingGadgetEl_.firstChild);
   }
-  if (this.curGadgetEl_) {
-    this.curGadgetEl_.removeChild(this.curGadgetEl_.firstChild);
+  if (this.currentGadgetEl_ && this.currentGadgetEl_.firstChild) {
+    this.currentGadgetEl_.removeChild(this.currentGadgetEl_.firstChild);
   }
-  if (this.loadingGadget_) {
-    this.loadingGadget_.dispose();
+  if (this.loadingGadgetHolder_) {
+    this.loadingGadgetHolder_.dispose();
   }
-  if (this.curGadget_) {
-    this.curGadget_.dispose();
+  if (this.currentGadgetHolder_) {
+    this.currentGadgetHolder_.dispose();
   }
 };
 
@@ -366,7 +372,7 @@ shindig.container.GadgetSite.prototype.s
 shindig.container.GadgetSite.prototype.onload_ = function() {
   this.loaded_ = true;
   try {
-    gadgets.rpc.call(this.loadingGadget_.getIframeId(), 'onLoad', null);
+    gadgets.rpc.call(this.loadingGadgetHolder_.getIframeId(), 'onLoad', null);
     if (this.resizeOnLoad_) {
       // TODO need a value for setHeight
       this.setHeight();
@@ -378,12 +384,12 @@ shindig.container.GadgetSite.prototype.o
 
   this.swapBuffers_();
 
-  if (this.curGadget_) {
-    this.curGadget_.dispose();
+  if (this.currentGadgetHolder_) {
+    this.currentGadgetHolder_.dispose();
   }
 
-  this.curGadget_ = this.loadingGadget_;
-  this.loadingGadget_ = null;
+  this.currentGadgetHolder_ = this.loadingGadgetHolder_;
+  this.loadingGadgetHolder_ = null;
 };
 
 
@@ -395,12 +401,30 @@ shindig.container.GadgetSite.prototype.s
   if (this.loadingGadgetEl_) {
     this.loadingGadgetEl_.style.left = '';
     this.loadingGadgetEl_.style.position = '';
-    this.curGadgetEl_.style.position = 'absolute';
-    this.curGadgetEl_.style.left = '-2000px';
+    this.currentGadgetEl_.style.position = 'absolute';
+    this.currentGadgetEl_.style.left = '-2000px';
 
     // Swap references;  cur_ will now again be what's visible
-    var oldCur = this.curGadgetEl_;
-    this.curGadgetEl_ = this.loadingGadgetEl_;
+    var oldCur = this.currentGadgetEl_;
+    this.currentGadgetEl_ = this.loadingGadgetEl_;
     this.loadingGadgetEl_ = oldCur;
   }
 };
+
+
+/**
+ * Default height of gadget. Refer to --
+ * http://code.google.com/apis/gadgets/docs/legacy/reference.html.
+ * @type {number}
+ * @private
+ */
+shindig.container.GadgetSite.DEFAULT_HEIGHT_ = 200;
+
+
+/**
+ * Default width of gadget. Refer to --
+ * http://code.google.com/apis/gadgets/docs/legacy/reference.html.
+ * @type {number}
+ * @private
+ */
+shindig.container.GadgetSite.DEFAULT_WIDTH_ = 320;

Modified: shindig/trunk/features/src/main/javascript/features/container/service.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/service.js?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/service.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/service.js Mon Sep 13 19:58:45 2010
@@ -43,12 +43,6 @@ shindig.container.Service = function(opt
       shindig.container.ServiceConfig.API_PATH, '/api/rpc/cs'));
   
   /**
-   * @type {boolean}
-   */
-  this.sameDomain_ = Boolean(shindig.container.util.getSafeJsonValue(config,
-      shindig.container.ServiceConfig.SAME_DOMAIN, false));
-
-  /**
    * Map of gadget URLs to cached gadgetInfo response.
    * @type {Object}
    */
@@ -76,9 +70,8 @@ shindig.container.Service.prototype.onCo
 
 /**
  * Do an immediate fetch of gadgets metadata for gadgets in request.ids, for
- * container request.container, with its results mutated by
- * request.sameDomain and request.aspDomain. The appropriate optional
- * callback opt_callback will be called, after a response is received.
+ * container request.container. The optional callback opt_callback will be
+ * called, after a response is received.
  * @param {Object} request JSON object representing the request.
  * @param {function(Object)=} opt_callback function to call upon data receive.
  */
@@ -96,7 +89,6 @@ shindig.container.Service.prototype.getG
     } else {
       for (var id in response) {
         var gadgetInfo = response[id];
-        self.processSameDomain_(gadgetInfo);
         self.cachedMetadatas_[id] = gadgetInfo;
       }
       callback(response);
@@ -149,20 +141,6 @@ shindig.container.Service.prototype.getC
 
 
 /**
- * @param {Object} gadgetInfo
- * @private
- */
-shindig.container.Service.prototype.processSameDomain_ = function(gadgetInfo) {
-  if (this.sameDomain_ && gadgetInfo['sameDomain']) {
-    var views = gadgetInfo['views'] || {};
-    for (var view in views) {
-      views[view]['iframeHost'] = this.apiHost_;
-    }
-  }
-};
-
-
-/**
  * Initialize OSAPI endpoint methods/interfaces.
  * @private
  */
@@ -198,5 +176,3 @@ shindig.container.ServiceConfig = {};
 shindig.container.ServiceConfig.API_HOST = 'apiHost';
 // Path to fetch gadget information, via XHR. 
 shindig.container.ServiceConfig.API_PATH = 'apiPath';
-// Toggle to render gadgets in the same domain. 
-shindig.container.ServiceConfig.SAME_DOMAIN = 'sameDomain';

Modified: shindig/trunk/features/src/main/javascript/features/container/util.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/util.js?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/util.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/util.js Mon Sep 13 19:58:45 2010
@@ -25,12 +25,6 @@
 /**
  * @type {Object}
  */
-shindig.container = {};
-
-
-/**
- * @type {Object}
- */
 shindig.container.util = {};
 
 
@@ -65,6 +59,47 @@ shindig.container.util.mergeJsons = func
 };
 
 
+shindig.container.util.cloneJson = function(json) {
+	
+};
+
+/**
+ * Construct a JSON request to get gadget metadata. For now, this will request
+ * a super-set of data needed for all CC APIs requiring gadget metadata, since
+ * the caching of response is not additive.
+ * @param {Array} A list of gadget URLs.
+ * @return {Object} the resulting JSON.
+ */
+shindig.container.util.newMetadataRequest = function(gadgetUrls) {
+  return {
+      'container': window.__CONTAINER,
+      'ids': gadgetUrls,
+      'fields': [
+          'iframeUrl',
+          'modulePrefs.*',
+          'needsTokenRefresh',
+          'userPrefs.*',
+          'views.preferredHeight',
+          'views.preferredWidth'
+      ]
+  };
+};
+
+
+/**
+ * Construct a JSON request to get gadget token.
+ * @param {Array} A list of gadget URLs.
+ * @return {Object} the resulting JSON.
+ */
+shindig.container.util.newTokenRequest = function(gadgetUrls) {
+  return {
+      'container': window.__CONTAINER,
+      'ids': gadgetUrls,
+      'fields': [ 'token' ]
+  };
+};
+
+
 /**
  * Extract keys from a JSON to an array.
  * @param {Object} json to extract keys from.

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java Mon Sep 13 19:58:45 2010
@@ -72,6 +72,7 @@ public class GadgetsHandlerApi {
     public ModulePrefs getModulePrefs();
     public Map<String, UserPref> getUserPrefs();
     public Map<String, View> getViews();
+    public Boolean getNeedsTokenRefresh();
   }
 
   public enum ViewContentType {

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java Mon Sep 13 19:58:45 2010
@@ -126,7 +126,11 @@ public class GadgetsHandlerService {
     String iframeUrl =
         (fields.contains("iframeurl") || fields.contains(BeanFilter.ALL_FIELDS)) ?
             iframeUriManager.makeRenderingUri(gadget).toString() : null;
-    return createMetadataResponse(context.getUrl(), gadget.getSpec(), iframeUrl, fields);
+    Boolean needsTokenRefresh =
+        (fields.contains("needstokenrefresh") || fields.contains(BeanFilter.ALL_FIELDS)) ?
+            gadget.getAllFeatures().contains("auth-refresh") : null;
+    return createMetadataResponse(context.getUrl(), gadget.getSpec(), iframeUrl,
+        needsTokenRefresh, fields);
   }
 
   /**
@@ -230,12 +234,15 @@ public class GadgetsHandlerService {
   }
 
   private GadgetsHandlerApi.MetadataResponse createMetadataResponse(
-      Uri url, GadgetSpec spec, String iframeUrl, Set<String> fields) {
+      Uri url, GadgetSpec spec, String iframeUrl, Boolean needsTokenRefresh,
+      Set<String> fields) {
     return (GadgetsHandlerApi.MetadataResponse) beanFilter.createFilteredBean(
         beanDelegator.createDelegator(spec, GadgetsHandlerApi.MetadataResponse.class,
             ImmutableMap.<String, Object>of(
-                "url", url, "error", BeanDelegator.NULL,
-                "iframeurl", BeanDelegator.nullable(iframeUrl))),
+                "url", url,
+                "error", BeanDelegator.NULL,
+                "iframeurl", BeanDelegator.nullable(iframeUrl),
+                "needstokenrefresh", BeanDelegator.nullable(needsTokenRefresh))),
         fields);
   }
 

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java Mon Sep 13 19:58:45 2010
@@ -23,6 +23,7 @@ import org.apache.shindig.common.uri.Uri
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.process.Processor;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
@@ -64,10 +65,17 @@ public class FakeProcessor extends Proce
           "<Content type=\"html\">Hello, world</Content>" +
           "</Module>";
 
+  private final FeatureRegistry featureRegistry;
+
   public FakeProcessor() {
+    this(null);
+  }
+
+  public FakeProcessor(FeatureRegistry featureRegistry) {
     super(null, null, null, null, null);
     this.gadgets.put(FakeProcessor.SPEC_URL, FakeProcessor.SPEC_XML);
     this.gadgets.put(FakeProcessor.SPEC_URL2, FakeProcessor.SPEC_XML2);
+    this.featureRegistry = featureRegistry;
   }
 
   @Override
@@ -84,7 +92,8 @@ public class FakeProcessor extends Proce
       return new Gadget()
           .setContext(context)
           .setSpec(spec)
-          .setCurrentView(view);
+          .setCurrentView(view)
+          .setGadgetFeatureRegistry(featureRegistry);
     } catch (GadgetException e) {
       throw new RuntimeException(e);
     }

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java?rev=996670&r1=996669&r2=996670&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java Mon Sep 13 19:58:45 2010
@@ -19,12 +19,14 @@
 package org.apache.shindig.gadgets.servlet;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.auth.SecurityTokenCodec;
 import org.apache.shindig.auth.SecurityTokenException;
 import org.apache.shindig.common.EasyMockTestCase;
 import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.protocol.conversion.BeanDelegator;
 import org.apache.shindig.protocol.conversion.BeanFilter;
@@ -45,7 +47,8 @@ public class GadgetHandlerServiceTest ex
   private final BeanDelegator delegator = new BeanDelegator(
     GadgetsHandlerService.apiClasses, GadgetsHandlerService.enumConversionMap);
 
-  private final FakeProcessor processor = new FakeProcessor();
+  private final FeatureRegistry mockRegistry = mock(FeatureRegistry.class);
+  private final FakeProcessor processor = new FakeProcessor(mockRegistry);
   private final FakeIframeUriManager urlGenerator = new FakeIframeUriManager();
 
   private FakeSecurityTokenCodec tokenCodec;
@@ -73,9 +76,12 @@ public class GadgetHandlerServiceTest ex
     GadgetsHandlerApi.MetadataRequest request = createMetadataRequest(
         FakeProcessor.SPEC_URL, CONTAINER, "view",
         createTokenData(null, null), ImmutableList.of("*"));
+    EasyMock.expect(mockRegistry.getFeatures(EasyMock.isA(List.class)))
+        .andReturn(Lists.newArrayList("auth-refresh"));
     replay();
     GadgetsHandlerApi.MetadataResponse response = gadgetHandler.getMetadata(request);
     assertEquals(FakeIframeUriManager.DEFAULT_IFRAME_URI.toString(), response.getIframeUrl());
+    assertTrue(response.getNeedsTokenRefresh());
     assertEquals(1, response.getViews().size());
     assertTrue(response.getViews().get("default").getContent().contains("Hello, world" ));
     assertEquals(FakeProcessor.SPEC_TITLE, response.getModulePrefs().getTitle());
@@ -105,7 +111,6 @@ public class GadgetHandlerServiceTest ex
     verify();
   }
 
-
   @Test(expected = ProcessingException.class)
   public void testGetMetadataNoContainer() throws Exception {
     GadgetsHandlerApi.MetadataRequest request = createMetadataRequest(
@@ -115,7 +120,6 @@ public class GadgetHandlerServiceTest ex
     GadgetsHandlerApi.MetadataResponse response = gadgetHandler.getMetadata(request);
   }
 
-
   @Test(expected = ProcessingException.class)
   public void testGetMetadataNoUrl() throws Exception {
     GadgetsHandlerApi.MetadataRequest request = createMetadataRequest(
@@ -147,6 +151,8 @@ public class GadgetHandlerServiceTest ex
   public void testGetMetadataNoToken() throws Exception {
     GadgetsHandlerApi.MetadataRequest request = createMetadataRequest(
         FakeProcessor.SPEC_URL, CONTAINER, "view", null, ImmutableList.of("*"));
+    EasyMock.expect(mockRegistry.getFeatures(EasyMock.isA(List.class)))
+        .andReturn(Lists.newArrayList("auth-refresh"));
     replay();
     GadgetsHandlerApi.MetadataResponse response = gadgetHandler.getMetadata(request);
     assertEquals(FakeIframeUriManager.DEFAULT_IFRAME_URI.toString(), response.getIframeUrl());