You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ch...@apache.org on 2010/02/09 09:29:28 UTC
svn commit: r907966 - in /shindig/trunk/php/src/gadgets: GadgetFactory.php
GadgetFeatureRegistry.php render/GadgetBaseRenderer.php
render/GadgetRenderer.php render/GadgetUrlRenderer.php servlet/JsServlet.php
Author: chabotc
Date: Tue Feb 9 08:29:28 2010
New Revision: 907966
URL: http://svn.apache.org/viewvc?rev=907966&view=rev
Log:
Fix external feature code generation to include dependencies (SHINDIG-1260) by Jacky Wang
Modified:
shindig/trunk/php/src/gadgets/GadgetFactory.php
shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php
shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php
shindig/trunk/php/src/gadgets/render/GadgetRenderer.php
shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php
shindig/trunk/php/src/gadgets/servlet/JsServlet.php
Modified: shindig/trunk/php/src/gadgets/GadgetFactory.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/GadgetFactory.php?rev=907966&r1=907965&r2=907966&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/GadgetFactory.php (original)
+++ shindig/trunk/php/src/gadgets/GadgetFactory.php Tue Feb 9 08:29:28 2010
@@ -72,7 +72,7 @@
$found = $missing = array();
if (! $this->context->getRegistry()->resolveFeatures(
array_merge($gadget->gadgetSpec->requiredFeatures, $gadget->gadgetSpec->optionalFeatures),
- $found, $missing, true)) {
+ $found, $missing)) {
$requiredMissing = false;
foreach ($missing as $featureName) {
if (in_array($featureName, $gadget->gadgetSpec->requiredFeatures)) {
Modified: shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php?rev=907966&r1=907965&r2=907966&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php (original)
+++ shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php Tue Feb 9 08:29:28 2010
@@ -28,7 +28,8 @@
public $features;
private $coreDone = false;
private $coreFeaturs;
-
+ private $sortedFeatures;
+
public function __construct($featurePath) {
$this->registerFeatures($featurePath);
}
@@ -86,90 +87,41 @@
return $ret;
}
- public function resolveFeatures($needed, &$resultsFound, &$resultsMissing, $isExpand) {
+ public function resolveFeatures($needed, &$resultsFound, &$resultsMissing) {
$resultsFound = array();
$resultsMissing = array();
if (! count($needed)) {
- // Shortcut for gadgets that don't have any explicit dependencies.
- $resultsFound = $this->coreFeatures;
- return true;
+ $needed = $this->coreFeatures;
}
foreach ($needed as $featureName) {
$feature = isset($this->features[$featureName]) ? $this->features[$featureName] : null;
if ($feature == null) {
$resultsMissing[] = $featureName;
} else {
- $this->addFeatureToResults($resultsFound, $feature, $isExpand);
+ $this->addFeatureToResults($resultsFound, $feature);
}
}
return count($resultsMissing) == 0;
}
- public function sortFeatures($features, $forcedJsLibs, &$sortedFeatureGroups) {
- $sortedFeatureGroups = array();
- if (empty($features)) return;
-
- // Topological sorting with constrain
- // Build the topology matrix
- $sortedFeatures = array();
- $reverseDeps = array();
- foreach ($features as $feature) {
- $reverseDeps[$feature] = array();
- }
- $depCount = array();
- foreach ($features as $feature) {
- $deps = $this->features[$feature]['deps'];
- $deps = array_uintersect($deps, $features, "strcasecmp");
- $depCount[$feature] = count($deps);
- foreach ($deps as $dep) {
- $reverseDeps[$dep][] = $feature;
- }
+ public function sortFeatures($features, &$sortedFeatures) {
+ if (empty($features)) {
+ return;
}
-
- // iterate to do the sorting
- $prevIsForcedJsLibs = true;
- $featureQueue = array();
- while (! empty($depCount)) {
- $fail = true;
- while (! empty($depCount)) { // get grouped features greedily
- $foundAll = true;
- foreach ($depCount as $feature => $count) {
- if ($count != 0) continue;
- $fail = false; // found at least one root node
- if ((! $prevIsForcedJsLibs) ^ in_array($feature, $forcedJsLibs)) {
- $foundAll = false;
- $featureQueue[] = $feature;
- foreach ($reverseDeps[$feature] as $reverseDep) {
- $depCount[$reverseDep] -= 1;
- }
- unset($depCount[$feature]);
- }
- }
- if ($foundAll) break;
- }
- if ($fail) {
- throw new GadgetException("Sorting feature dependence failed: it contains ring!");
- }
- if (! empty($featureQueue)) {
- if ($prevIsForcedJsLibs) {
- $sortedFeatureGroups[] = array('type' => 'external', 'features' => $featureQueue);
- } else {
- $sortedFeatureGroups[] = array('type' => 'inline', 'features' => $featureQueue);
- }
+ $sortedFeatures = array();
+ foreach ($this->sortedFeatures as $feature) {
+ if (in_array($feature, $features)) {
+ $sortedFeatures[] = $feature;
}
- $prevIsForcedJsLibs = ! $prevIsForcedJsLibs;
- $featureQueue = array();
}
}
- private function addFeatureToResults(&$results, $feature, $isExpand) {
+ private function addFeatureToResults(&$results, $feature) {
if (in_array($feature['name'], $results)) {
return;
}
- if ($isExpand) {
- foreach ($feature['deps'] as $dep) {
- $this->addFeatureToResults($results, $this->features[$dep], true);
- }
+ foreach ($feature['deps'] as $dep) {
+ $this->addFeatureToResults($results, $this->features[$dep]);
}
if (!in_array($feature['name'], $results)) {
$results[] = $feature['name'];
@@ -214,6 +166,41 @@
$this->features[$key]['deps'] = array_merge($entry['deps'], $this->coreFeatures);
}
}
+ // Topologically sort all features according to their dependency
+ $features = array();
+ foreach ($this->features as $feature) {
+ $features[] = $feature['name'];
+ }
+ $sortedFeatures = array();
+ $reverseDeps = array();
+ foreach ($features as $feature) {
+ $reverseDeps[$feature] = array();
+ }
+ $depCount = array();
+ foreach ($features as $feature) {
+ $deps = $this->features[$feature]['deps'];
+ $deps = array_uintersect($deps, $features, "strcasecmp");
+ $depCount[$feature] = count($deps);
+ foreach ($deps as $dep) {
+ $reverseDeps[$dep][] = $feature;
+ }
+ }
+ while (! empty($depCount)) {
+ $fail = true;
+ foreach ($depCount as $feature => $count) {
+ if ($count != 0) continue;
+ $fail = false;
+ $sortedFeatures[] = $feature;
+ foreach ($reverseDeps[$feature] as $reverseDep) {
+ $depCount[$reverseDep] -= 1;
+ }
+ unset($depCount[$feature]);
+ }
+ if ($fail && ! empty($depCount)) {
+ throw new GadgetException("Sorting feature dependence failed: it contains ring!");
+ }
+ }
+ $this->sortedFeatures = $sortedFeatures;
}
/**
Modified: shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php?rev=907966&r1=907965&r2=907966&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php (original)
+++ shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php Tue Feb 9 08:29:28 2010
@@ -300,25 +300,36 @@
public function getJavaScripts() {
$registry = $this->context->getRegistry();
$forcedJsLibs = $this->getForcedJsLibs();
- $sortedFeatureGroups = array();
- $registry->sortFeatures($this->gadget->features, $forcedJsLibs, $sortedFeatureGroups);
- $scripts = array();
-
- // if some of the feature libraries are externalized (through a browser cachable <script src="/gadgets/js/opensocial-0.9:settitle.js"> type url)
- // we inject the tag and don't inline those libs (and their dependencies)
- foreach ($sortedFeatureGroups as $featureGroup) {
- if ($featureGroup['type'] == 'inline') {
- $featureGroup['content'] = $registry->getFeaturesContent($featureGroup['features'], $this->context, true);
+ $externFeatures = array();
+ $inlineFeatures = array();
+ foreach ($this->gadget->features as $feature) {
+ if (in_array($feature, $forcedJsLibs)) {
+ $externFeatures[] = $feature;
} else {
- $featureGroup['content'] = Config::get('default_js_prefix') . $this->getJsUrl($featureGroup['features']) . "&container=" . $this->context->getContainer();
+ $inlineFeatures[] = $feature;
}
- $scripts[] = $featureGroup;
}
+ $sortedExternFeatures = array();
+ $sortedInlineFeatures = array();
+ $registry->sortFeatures($externFeatures, $sortedExternFeatures);
+ $registry->sortFeatures($inlineFeatures, $sortedInlineFeatures);
+ // if some of the feature libraries are externalized (through a browser cachable <script src="/gadgets/js/opensocial-0.9:settitle.js"> type url)
+ // we inject the tag and don't inline those libs (and their dependencies)
+ $scripts = array();
+ if (! empty($sortedExternFeatures)) {
+ $scripts[] = array(
+ 'type' => 'extern',
+ 'content' => Config::get('default_js_prefix') . $this->getJsUrl($sortedExternFeatures) . "&container=" . $this->context->getContainer()
+ );
+ }
$script = '';
+ foreach ($sortedInlineFeatures as $feature) {
+ $script .= $registry->getFeatureContent($feature, $this->context, true);
+ }
// Add the JavaScript initialization strings for the configuration, localization and preloads
$script .= "\n";
- $script .= $this->appendJsConfig($this->gadget, $sortedFeatureGroups);
+ $script .= $this->appendJsConfig($this->gadget, $sortedExternFeatures, $sortedInlineFeatures);
$script .= $this->appendMessages($this->gadget);
$script .= $this->appendPreloads($this->gadget);
if (count($this->dataInserts)) {
@@ -380,7 +391,13 @@
if (empty($forcedJsLibs)) {
return array();
} else {
- return explode(':', $forcedJsLibs);
+ $features = explode(':', $forcedJsLibs);
+ // expend features here
+ $resultsFound = array();
+ $resultsMissing = array();
+ $registry = $this->context->getRegistry();
+ $registry->resolveFeatures($features, $resultsFound, $resultsMissing);
+ return $resultsFound;
}
}
@@ -388,23 +405,19 @@
* Appends the javascript features configuration string
*
* @param Gadget $gadget
- * @param $featureGroups
+ * @param $externFeatures
+ * @param $inlineFeatures
* @return string
*/
- private function appendJsConfig(Gadget $gadget, $featureGroups) {
+ private function appendJsConfig(Gadget $gadget, $externFeatures, $inlineFeatures) {
$container = $this->context->getContainer();
$containerConfig = $this->context->getContainerConfig();
- $forcedJsLibs = $this->getForcedJsLibs();
$gadgetConfig = array();
$featureConfig = $containerConfig->getConfig($container, 'gadgets.features');
// TODO some day we should parse the forcedLibs too, and include their config selectivly as well.
// For now we just include everything.
- $features = array();
- foreach ($featureGroups as $featureGroup) {
- $features = array_merge($features, $featureGroup['features']);
- }
-
+ $features = array_merge($externFeatures, $inlineFeatures);
foreach ($features as $feature) {
if (! isset($gadgetConfig[$feature]) && ! empty($featureConfig[$feature])) {
$gadgetConfig[$feature] = $featureConfig[$feature];
Modified: shindig/trunk/php/src/gadgets/render/GadgetRenderer.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/render/GadgetRenderer.php?rev=907966&r1=907965&r2=907966&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/render/GadgetRenderer.php (original)
+++ shindig/trunk/php/src/gadgets/render/GadgetRenderer.php Tue Feb 9 08:29:28 2010
@@ -33,7 +33,7 @@
* generates the library string (core:caja:etc.js) including a checksum of all the
* javascript content (?v=<md5 of js>) for cache busting
*
- * @param string $libs
+ * @param string $features
* @param Gadget $gadget
* @return string the list of libraries in core:caja:etc.js?v=checksum> format
*/
Modified: shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php?rev=907966&r1=907965&r2=907966&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php (original)
+++ shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php Tue Feb 9 08:29:28 2010
@@ -40,17 +40,10 @@
$registry = $this->context->getRegistry();
// since the URL mode doesn't actually have the gadget XML body, it can't inline
// the javascript content anyway - thus could us just ignore the 'forcedJsLibs' part.
- $forcedJsLibs = array();
- $sortedFeatureGroups = array();
- $registry->sortFeatures($gadget->features, $forcedJsLibs, $sortedFeatureGroups);
+ $sortedFeatures = array();
+ $registry->sortFeatures($gadget->features, $sortedFeatures);
- // join the groups
- $features = array();
- foreach ($sortedFeatureGroups as $featureGroup) {
- $features = array_merge($features, $featureGroup['features']);
- }
-
- $query .= $this->appendLibsToQuery($features);
+ $query .= $this->appendLibsToQuery($sortedFeatures);
$query .= '&lang=' . urlencode(isset($_GET['lang']) ? $_GET['lang'] : 'en');
$query .= '&country=' . urlencode(isset($_GET['country']) ? $_GET['country'] : 'US');
if (substr($query, 0, 1) == '&') {
Modified: shindig/trunk/php/src/gadgets/servlet/JsServlet.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/servlet/JsServlet.php?rev=907966&r1=907965&r2=907966&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/servlet/JsServlet.php (original)
+++ shindig/trunk/php/src/gadgets/servlet/JsServlet.php Tue Feb 9 08:29:28 2010
@@ -56,7 +56,7 @@
$missing = array();
$context = new GadgetContext('GADGET');
$registry = new GadgetFeatureRegistry(Config::get('features_path'));
- if ($registry->resolveFeatures($needed, $found, $missing, false)) {
+ if ($registry->resolveFeatures($needed, $found, $missing)) {
$isGadgetContext = !isset($_GET["c"]) || $_GET['c'] == 0 ? true : false;
$jsData = '';
foreach ($found as $feature) {