Author: lindner
Date: Tue Mar 18 17:29:25 2008
New Revision: 638660

URL: http://svn.apache.org/viewvc?rev=638660&view=rev
Log:
Apply patch from Chris Chabot for SHINDIG-128
- Re-factored config.php and context class to be a bit more logical and 
readable.
- Added lazy loading to said context class which has some performance benefits.
- A modest start at adding JavaDoc documentation to the code


Modified:
    incubator/shindig/trunk/php/gadgets/config.php
    incubator/shindig/trunk/php/gadgets/index.php
    incubator/shindig/trunk/php/gadgets/src/BasicRemoteContent.php
    incubator/shindig/trunk/php/gadgets/src/CacheMemcache.php
    incubator/shindig/trunk/php/gadgets/src/Gadget.php
    incubator/shindig/trunk/php/gadgets/src/GadgetContext.php
    incubator/shindig/trunk/php/gadgets/src/GadgetServer.php
    incubator/shindig/trunk/php/gadgets/src/GadgetSpecParser.php
    incubator/shindig/trunk/php/gadgets/src/RemoteContent.php
    incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php
    incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php
    incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php
    incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php
    incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php
    incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php

Modified: incubator/shindig/trunk/php/gadgets/config.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/config.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/config.php (original)
+++ incubator/shindig/trunk/php/gadgets/config.php Tue Mar 18 17:29:25 2008
@@ -19,6 +19,11 @@
        'syndicator_config' =>  
realpath(dirname(__FILE__)).'/../../config/syndicator.js',
        'javascript_path' =>  realpath(dirname(__FILE__)).'/../../javascript/',
 
+       // If you want to use the yuicompressor 
(http://developer.yahoo.com/yui/compressor/) to minify your javascript
+       // set this to the yuicompressor-?.jar's file path
+       //NOTE: not used yet, will be in the next patch
+       'compressor_path' => 
realpath(dirname(__FILE__)).'/bin/yuicompressor-2.3.5.jar',
+
        // Configurable classes to use, this way we provide extensibility for 
what 
        // backends the gadget server uses for its logic functionality. 
        'blacklist_class' => 'BasicGadgetBlacklist',
@@ -46,10 +51,5 @@
        'cache_root'=> '/tmp/shindig',
        
        // In some cases we need to know the site root (for features 
forinstance)
-       'base_path'=> realpath(dirname(__FILE__)),
-
-       // We combine global and per request state in the config since it saves 
a good bit of code
-       // and global classes & variables, these are the HttpProcessingOptions
-       'ignoreCache' => (isset($_GET['nocache']) && intval($_GET['nocache']) 
== 1) || (isset($_GET['bpc']) && intval($_GET['bpc']) == 1),
-       'focedJsLibs' => isset($_GET['libs']) ? trim($_GET['libs']) : null
+       'base_path'=> realpath(dirname(__FILE__))
 );

Modified: incubator/shindig/trunk/php/gadgets/index.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/index.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/index.php (original)
+++ incubator/shindig/trunk/php/gadgets/index.php Tue Mar 18 17:29:25 2008
@@ -38,7 +38,7 @@
 
 function __autoload($className)
 {
-       require_once 'src/' . $className . '.php';
+       require 'src/' . $className . '.php';
 }
 
 $servletMap = array($config['web_prefix'] . '/files' => 'FilesServlet', 
$config['web_prefix'] . '/js' => 'JsServlet', $config['web_prefix'] . '/proxy' 
=> 'ProxyServlet', $config['web_prefix'] . '/ifr' => 'GadgetRenderingServlet', 
$config['web_prefix'] . '/rpc' => 'RpcServlet');

Modified: incubator/shindig/trunk/php/gadgets/src/BasicRemoteContent.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/BasicRemoteContent.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/BasicRemoteContent.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/BasicRemoteContent.php Tue Mar 18 
17:29:25 2008
@@ -20,7 +20,7 @@
 
 class BasicRemoteContent extends RemoteContent {
        
-       public function fetch($request)
+       public function fetch($request, $context)
        {
                global $config;
                $cache = new $config['data_cache']();
@@ -29,7 +29,7 @@
                        throw new RemoteContentException("Invalid request type 
in remoteContent");
                }
                // determine which requests we can load from cache, and which 
we have to actually fetch
-               if (! $config['ignoreCache'] && ($cachedRequest = 
$cache->get($request->toHash())) !== false) {
+               if (! $context->getIgnoreCache() && ($cachedRequest = 
$cache->get($request->toHash())) !== false) {
                        $ret = $cachedRequest;
                } else {
                        $ret = $remoteContentFetcher->fetchRequest($request);

Modified: incubator/shindig/trunk/php/gadgets/src/CacheMemcache.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/CacheMemcache.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/CacheMemcache.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/CacheMemcache.php Tue Mar 18 
17:29:25 2008
@@ -23,7 +23,6 @@
  * usefull in a multi-server envirionment then the file based caching,
  * (in a single server setup file based caching is actually faster)
  */
-
 class CacheMemcache extends Cache {
        private $connection = false;
 

Modified: incubator/shindig/trunk/php/gadgets/src/Gadget.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/Gadget.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/Gadget.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/Gadget.php Tue Mar 18 17:29:25 2008
@@ -32,7 +32,7 @@
        private $userPrefValues;
        private $messageBundle = array();
        // As in UserPref, no enums so fake it
-       public $contentTypes    = array('HTML', 'URL');
+       public $contentTypes = array('HTML', 'URL');
        public $id;
        public $author;
        public $authorEmail;
@@ -49,86 +49,88 @@
        public $title;
        public $titleUrl = null;
        public $userPrefs = array();
-       
-       public function __construct($id = false, $prefs = false)
+
+       public function __construct($id = false, $context)
        {
-               if ($id) $this->id = $id;
-               if ($prefs) $this->userPrefValues = $prefs;
+               if ($id)
+                       $this->id = $id;
+               if ($context->getUserPrefs())
+                       $this->setPrefs($context->getUserPrefs());
                $this->substitutions = new Substitutions();
                $this->jsLibraries = array();
        }
-       
+
        public function setId($id)
        {
                $this->id = $id;
        }
-       
+
        public function setPrefs($prefs)
        {
                $this->userPrefValues = $prefs;
        }
-       
+
        public function getAuthor()
        {
                return $this->substitutions->substitute($this->author);
        }
-       
+
        public function getAuthorEmail()
        {
                return $this->substitutions->substitute($this->authorEmail);
        }
-               
+
        public function getContentData($view = false)
        {
                if ($this->contentType != 'HTML') {
                        throw new SpecParserException("getContentData() 
requires contentType HTML");
                }
-               if (empty($view) || !$view) {
+               if (empty($view) || ! $view) {
                        $view = DEFAULT_VIEW;
                }
                return 
$this->substitutions->substitute(isset($this->contentData[$view]) ? 
trim($this->contentData[$view]) : '');
        }
-       
+
        public function getContentHref()
        {
                return $this->substitutions->substitute($this->getContentType() 
== 'URL' ? $this->contentHref : null);
        }
-       
+
        public function getMessageBundle()
        {
                return $this->messageBundle;
        }
-       
+
        public function getDescription()
        {
                return $this->substitutions->substitute($this->description);
        }
-       
+
        public function getDirectoryTitle()
        {
                return $this->substitutions->substitute($this->directoryTitle);
        }
-               
+
        public function getId()
        {
                return $this->id;
        }
-       
+
        public function getJsLibraries()
        {
                return $this->jsLibraries;
        }
-       
+
        public function addJsLibrary($library)
        {
                $this->jsLibraries[] = $library;
        }
-       
+
        public function getLocaleSpecs()
        {
                return $this->localeSpecs;
        }
-       
+
        public function getFeatureParams($gadget, $feature)
        {
                //FIXME not working atm
@@ -140,65 +142,65 @@
                        return $spec->getParams();
                }
        }
-       
+
        public function getPreloads()
        {
                $ret = array();
-               foreach ( $this->preloads as $preload ) {
+               foreach ($this->preloads as $preload) {
                        $ret[] = $this->substitutions->substitute($preload);
                }
                return $ret;
        }
-       
+
        public function getRequires()
        {
                return $this->requires;
        }
-       
+
        public function getScreenshot()
        {
                return $this->substitutions->substitute($this->screenshot);
        }
-       
+
        public function getSubstitutions()
        {
                return $this->substitutions;
        }
-       
+
        public function getThumbnail()
        {
                return $this->substitutions->substitute($this->thumbnail);
        }
-       
+
        public function getTitle()
        {
                return $this->substitutions->substitute($this->title);
        }
-       
+
        public function getTitleURI()
        {
                $ret = null;
-               if (!empty($this->titleURI)) {
+               if (! empty($this->titleURI)) {
                        $ret = 
$this->substitutions->substitute($this->titleURI);
                }
                return $ret;
        }
-       
+
        public function getUserPrefs()
        {
                return $this->userPrefs;
        }
-       
+
        public function getUserPrefValues()
        {
                return $this->userPrefValues;
        }
-       
+
        public function setMessageBundle($messageBundle)
        {
                $this->messageBundle = $messageBundle;
        }
-       
+
        /* gadget Spec functions */
        public function addContent($view, $data)
        {
@@ -210,7 +212,7 @@
                }
                $this->contentData[$view] .= $data;
        }
-                               
+
        public function getContentType()
        {
                return $this->contentType;
@@ -221,17 +223,17 @@
        public $url;
        public $locale;
        public $rightToLeft;
-       
+
        public function getURI()
        {
                return $this->url;
        }
-       
+
        public function getLocale()
        {
                return $this->locale;
        }
-       
+
        public function isRightToLeft()
        {
                return $this->rightToLeft;
@@ -242,17 +244,17 @@
        public $name;
        public $params = array();
        public $optional;
-       
+
        public function getName()
        {
                return $this->name;
        }
-       
+
        public function getParams()
        {
                return $this->params;
        }
-       
+
        public function isOptional()
        {
                return $this->optional;
@@ -268,32 +270,32 @@
        public $required;
        public $enumValues;
        public $contentType;
-       
+
        public function getName()
        {
                return $this->name;
        }
-       
+
        public function getDisplayName()
        {
                return $this->displayName;
        }
-       
+
        public function getDefaultValue()
        {
                return $this->defaultValue;
        }
-       
+
        public function isRequired()
        {
                return $this->required;
        }
-       
+
        public function getDataType()
        {
                return $this->dataType;
        }
-       
+
        public function getEnumValues()
        {
                return $this->enumValues;

Modified: incubator/shindig/trunk/php/gadgets/src/GadgetContext.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/GadgetContext.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/GadgetContext.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/GadgetContext.php Tue Mar 18 
17:29:25 2008
@@ -18,40 +18,300 @@
  * 
  */
 
+define('DEFAULT_VIEW', 'default');
+
 /*
- * the httpFetcher (RemoteContentFetcher) is our cache too, so we skip the
- * messageBundleCache vars and params.
+ * GadgetContext contains all contextual variables and classes that are 
relevant for this request,
+ * such as url, httpFetcher, feature registry, etc.
+ * Server wide variables are stored in config.php in the global $config array 
  */
-
 class GadgetContext {
-       private $httpFetcher;
-       private $locale;
-       private $renderingContext;
-       private $registry;
-       
-       public function __construct(RemoteContent $httpFetcher, Locale $locale, 
$renderingContext, GadgetFeatureRegistry $registry)
+       private $httpFetcher = null;
+       private $locale = null;
+       private $renderingContext = null;
+       private $registry = null;
+       private $userPrefs = null;
+       private $gadgetId = null;
+       private $view = null;
+       private $moduleId = null;
+       private $url = null;
+       private $cache = null;
+       private $blacklist = null;
+       private $ignoreCache = null;
+       private $forcedJsLibs = null;
+
+       public function __construct($renderingContext)
+       {
+               // Rendering context is set by the calling event handler 
(either GADGET or CONTAINER)
+               $this->setRenderingContext($renderingContext);
+               
+               // Request variables
+               $this->setIgnoreCache($this->getIgnoreCacheParam());
+               $this->setForcedJsLibs($this->getFocedJsLibsParam());
+               $this->setUrl($this->getUrlParam());
+               $this->setModuleId($this->getModuleIdParam());
+               $this->setView($this->getViewParam());
+               //NOTE All classes are inititialized when called (aka lazy 
loading) because we don't 
+               //need all of them in every situation
+       }
+
+       private function getIgnoreCacheParam()
+       {
+               // Support both the old Orkut style &bpc and new standard style 
&nocache= params
+               return (isset($_GET['nocache']) && intval($_GET['nocache']) == 
1) || (isset($_GET['bpc']) && intval($_GET['bpc']) == 1);
+       }
+
+       private function getFocedJsLibsParam()
+       {
+               return isset($_GET['libs']) ? trim($_GET['libs']) : null;
+       }
+
+       private function getUrlParam()
+       {
+               if (!empty($_GET['url'])) {
+                       return $_GET['url'];
+               } elseif (!empty($_POST['url'])) {
+                       return $_POST['url'];
+               }
+               return null;
+       }
+
+       private function getModuleIdParam()
+       {
+               return isset($_GET['mid']) && is_numeric($_GET['mid']) ? 
intval($_GET['mid']) : 0;
+       }
+
+       private function getViewParam()
+       {
+               return ! empty($_GET['view']) ? $_GET['view'] : DEFAULT_VIEW;
+       }
+
+       private function instanceBlacklist()
+       {
+               global $config;
+               if (! empty($config['blacklist_class'])) {
+                       return new $config['blacklist_class']();
+               } else {
+                       return null;
+               }
+       }
+
+       private function instanceUserPrefs()
+       {
+               global $config;
+               $prefs = array();
+               foreach ($_GET as $key => $val) {
+                       if (substr($key, 0, 
strlen($config['userpref_param_prefix'])) == $config['userpref_param_prefix']) {
+                               $name = substr($key, 
strlen($config['userpref_param_prefix']));
+                               $prefs[$name] = $val;
+                       }
+               }
+               return new UserPrefs($prefs);
+       }
+
+       private function instanceGadgetId($url, $moduleId)
+       {
+               return new GadgetId($url, $moduleId);
+       }
+
+       private function instanceHttpFetcher()
+       {
+               global $config;
+               return new $config['remote_content']();
+       }
+
+       private function instanceCache()
+       {
+               global $config;
+               return new $config['data_cache']();
+       }
+
+       private function instanceRegistry()
+       {
+               global $config;
+               // Profiling showed 40% of the processing time was spend in the 
feature registry
+               // So by caching this and making it a one time initialization, 
we almost double the performance  
+               if (! ($registry = 
$this->getCache()->get(sha1($config['features_path'])))) {
+                       $registry = new 
GadgetFeatureRegistry($config['features_path']);
+                       $this->getCache()->set(sha1($config['features_path']), 
$registry);
+               }
+               return $registry;
+       }
+
+       private function instanceLocale()
+       {
+               $language = 'all';
+               $country = 'all';
+               if (! empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+                       $acceptLanguage = explode(';', 
$_SERVER['HTTP_ACCEPT_LANGUAGE']);
+                       $acceptLanguage = $acceptLanguage[0];
+                       if (strpos($acceptLanguage, '-') !== false) {
+                               $lang = explode('-', $acceptLanguage);
+                               $language = $lang[0];
+                               $country = $lang[1];
+                               if (strpos($country, ',') !== false) {
+                                       $country = explode(',', $country);
+                                       $country = $country[0];
+                               }
+                       } else {
+                               $language = $acceptLanguage;
+                       }
+               
+               }
+               return new Locale($language, $country);
+       }
+
+       public function getCache()
+       {
+               if ($this->cache == null) {
+                       $this->setCache($this->instanceCache());
+               }
+               return $this->cache;
+       }
+
+       public function getGadgetId()
+       {
+               if ($this->gadgetId == null) {
+                       
$this->setGadgetId($this->instanceGadgetId($this->getUrl(), 
$this->getModuleId()));
+               }
+               return $this->gadgetId;
+       }
+
+       public function getModuleId()
+       {
+               return $this->moduleId;
+       }
+
+       public function getRegistry()
+       {
+               if ($this->registry == null) {
+                       $this->setRegistry($this->instanceRegistry());
+               }
+               return $this->registry;
+       }
+
+       public function getUrl()
+       {
+               return $this->url;
+       }
+
+       public function getUserPrefs()
+       {
+               if ($this->userPrefs == null) {
+                       $this->setUserPrefs($this->instanceUserPrefs());
+               }
+               return $this->userPrefs;
+       }
+
+       public function getView()
+       {
+               return $this->view;
+       }
+
+       public function setBlacklist($blacklist)
+       {
+               $this->blacklist = $blacklist;
+       }
+
+       public function setCache($cache)
+       {
+               $this->cache = $cache;
+       }
+
+       public function setGadgetId($gadgetId)
+       {
+               $this->gadgetId = $gadgetId;
+       }
+
+       public function setHttpFetcher($httpFetcher)
        {
                $this->httpFetcher = $httpFetcher;
+       }
+
+       public function setLocale($locale)
+       {
                $this->locale = $locale;
-               $this->renderingContext = $renderingContext;
+       }
+
+       public function setModuleId($moduleId)
+       {
+               $this->moduleId = $moduleId;
+       }
+
+       public function setRegistry($registry)
+       {
                $this->registry = $registry;
        }
-       
+
+       public function setRenderingContext($renderingContext)
+       {
+               $this->renderingContext = $renderingContext;
+       }
+
+       public function setUrl($url)
+       {
+               $this->url = $url;
+       }
+
+       public function setUserPrefs($userPrefs)
+       {
+               $this->userPrefs = $userPrefs;
+       }
+
+       public function setView($view)
+       {
+               $this->view = $view;
+       }
+
+       public function setIgnoreCache($ignoreCache)
+       {
+               $this->ignoreCache = $ignoreCache;
+       }
+
+       public function setForcedJsLibs($forcedJsLibs)
+       {
+               $this->forcedJsLibs = $forcedJsLibs;
+       }
+
+       public function getIgnoreCache()
+       {
+               return $this->ignoreCache;
+       }
+
+       public function getForcedJsLibs()
+       {
+               return $this->forcedJsLibs;
+       }
+
+       public function getBlacklist()
+       {
+               if ($this->blacklist == null) {
+                       $this->setBlacklist($this->instanceBlacklist());
+               }
+               return $this->blacklist;
+       }
+
        public function getRenderingContext()
        {
                return $this->renderingContext;
        }
-       
+
        public function getHttpFetcher()
        {
+               if ($this->httpFetcher == null) {
+                       $this->setHttpFetcher($this->instanceHttpFetcher());
+               }
                return $this->httpFetcher;
        }
-       
+
        public function getLocale()
        {
+               if ($this->locale == null) {
+                       $this->setLocale($this->instanceLocale());
+               }
                return $this->locale;
        }
-       
+
        public function getFeatureRegistry()
        {
                return $this->registry;

Modified: incubator/shindig/trunk/php/gadgets/src/GadgetServer.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/GadgetServer.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/GadgetServer.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/GadgetServer.php Tue Mar 18 
17:29:25 2008
@@ -24,65 +24,48 @@
  */
 
 class GadgetServer {
-       private $registry;
-       private $blacklist;
-       private $gc;
-       private $gadgetId;
-       private $userPrefs;
-       private $renderingContext;
-       private $locale;
-       private $httpFetcher;
-       
-       public function processGadget($gadgetId, $userPrefs, $locale, $rctx, 
$httpFetcher, $registry)
-       {
-               global $config;
-               $this->gadgetId = $gadgetId;
-               $this->userPrefs = $userPrefs;
-               $this->renderingContext = $rctx;
-               $this->locale = $locale;
-               $this->registry = $registry;
-               $this->httpFetcher = $httpFetcher;
-               $this->gc = new GadgetContext($httpFetcher, $locale, $rctx, 
$registry);
-               $this->blacklist = new $config['blacklist_class']();
-               $gadget = $this->specLoad();
-               $this->featuresLoad($gadget);
+
+       public function processGadget($context)
+       {
+               $gadget = $this->specLoad($context);
+               $this->featuresLoad($gadget, $context);
                return $gadget;
        }
-       
-       private function specLoad()
+
+       private function specLoad($context)
        {
-               if ($this->blacklist != null && 
$this->blacklist->isBlacklisted($this->gadgetId->getURI())) {
+               if ($context->getBlacklist() != null && 
$context->getBlacklist()->isBlacklisted($context->getUrl())) {
                        throw new GadgetException("Gadget is blacklisted");
                }
-               $request = new RemoteContentRequest($this->gadgetId->getURI());
-               $xml = $this->httpFetcher->fetch($request);
+               $request = new RemoteContentRequest($context->geturl());
+               $xml = $context->getHttpFetcher()->fetch($request, $context);
                if ($xml->getHttpCode() != '200') {
                        throw new GadgetException("Failed to retrieve gadget 
content");
                }
                $specParser = new GadgetSpecParser();
-               $gadget = $specParser->parse($xml->getResponseContent(), 
$this->gadgetId, $this->userPrefs);
+               $gadget = $specParser->parse($xml->getResponseContent(), 
$context);
                return $gadget;
        }
-               
+
        private function getBundle($localeSpec, $context)
        {
                if ($localeSpec != null) {
                        $uri = $localeSpec->getURI();
                        if ($uri != null) {
                                $fetcher = $context->getHttpFetcher();
-                               $response = $fetcher->fetch(new 
RemoteContentRequest($uri));
+                               $response = $fetcher->fetch(new 
RemoteContentRequest($uri), $context);
                                $parser = new MessageBundleParser();
                                $bundle = 
$parser->parse($response->getResponseContent());
-                               return $bundle;                         
+                               return $bundle;
                        }
                }
                return null;
        }
-       
+
        private function localeSpec($gadget, $locale)
        {
                $localeSpecs = $gadget->getLocaleSpecs();
-               foreach ( $localeSpecs as $locSpec ) {
+               foreach ($localeSpecs as $locSpec) {
                        //fix me
                        if ($locSpec->getLocale()->equals($locale)) {
                                return $locSpec;
@@ -90,10 +73,10 @@
                }
                return null;
        }
-       
-       private function getLocaleSpec($gadget)
+
+       private function getLocaleSpec($gadget, $context)
        {
-               $locale = $this->gc->getLocale();
+               $locale = $context->getLocale();
                // en-US
                $localeSpec = $this->localeSpec($gadget, $locale);
                if ($localeSpec == null) {
@@ -106,15 +89,15 @@
                }
                return $localeSpec;
        }
-       
-       private function featuresLoad($gadget)
+
+       private function featuresLoad($gadget, $context)
        {
                //NOTE i've been a bit liberal here with folding code into this 
function, while it did get a bit long, the many include()'s are slowing us down
                // Should really clean this up a bit in the future though
-               $localeSpec = $this->getLocaleSpec($gadget);
+               $localeSpec = $this->getLocaleSpec($gadget, $context);
                
                // get the message bundle for this gadget
-               $bundle = $this->getBundle($localeSpec, $this->gc);
+               $bundle = $this->getBundle($localeSpec, $context);
                
                //FIXME this is a half-assed solution between following the 
refactoring and maintaining some of the old code, fixing this up later
                $gadget->setMessageBundle($bundle);
@@ -142,7 +125,7 @@
                
                // userPref's
                $upValues = $gadget->getUserPrefValues();
-               foreach ( $gadget->getUserPrefs() as $pref ) {
+               foreach ($gadget->getUserPrefs() as $pref) {
                        $name = $pref->getName();
                        $value = $upValues->getPref($name);
                        if ($value == null) {
@@ -158,7 +141,7 @@
                $requires = $gadget->getRequires();
                $needed = array();
                $optionalNames = array();
-               foreach ( $requires as $key => $entry ) {
+               foreach ($requires as $key => $entry) {
                        $needed[] = $key;
                        if ($entry->isOptional()) {
                                $optionalNames[] = $key;
@@ -168,8 +151,8 @@
                $resultsMissing = array();
                $missingOptional = array();
                $missingRequired = array();
-               $this->registry->getIncludedFeatures($needed, $resultsFound, 
$resultsMissing);
-               foreach ( $resultsMissing as $missingResult ) {
+               $context->getRegistry()->getIncludedFeatures($needed, 
$resultsFound, $resultsMissing);
+               foreach ($resultsMissing as $missingResult) {
                        if (in_array($missingResult, $optionalNames)) {
                                $missingOptional[$missingResult] = 
$missingResult;
                        } else {
@@ -181,18 +164,18 @@
                }
                // create features
                $features = array();
-               foreach ( $resultsFound as $entry ) {
-                       $features[$entry] = 
$this->registry->getEntry($entry)->getFeature()->create();
+               foreach ($resultsFound as $entry) {
+                       $features[$entry] = 
$context->getRegistry()->getEntry($entry)->getFeature()->create();
                }
                // prepare them
-               foreach ( $features as $key => $feature ) {
-                       $params = $gadget->getFeatureParams($gadget, 
$this->registry->getEntry($key));
-                       $feature->prepare($gadget, $this->gc, $params);
+               foreach ($features as $key => $feature) {
+                       $params = $gadget->getFeatureParams($gadget, 
$context->getRegistry()->getEntry($key));
+                       $feature->prepare($gadget, $context, $params);
                }
                // and process them
-               foreach ( $features as $key => $feature ) {
-                       $params = $gadget->getFeatureParams($gadget, 
$this->registry->getEntry($key));
-                       $feature->process($gadget, $this->gc, $params);
+               foreach ($features as $key => $feature) {
+                       $params = $gadget->getFeatureParams($gadget, 
$context->getRegistry()->getEntry($key));
+                       $feature->process($gadget, $context, $params);
                }
        }
 }

Modified: incubator/shindig/trunk/php/gadgets/src/GadgetSpecParser.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/GadgetSpecParser.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/GadgetSpecParser.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/GadgetSpecParser.php Tue Mar 18 
17:29:25 2008
@@ -18,12 +18,12 @@
  * 
  */
 
-class SpecParserException extends Exception {
-}
+class SpecParserException extends Exception {}
 
 class GadgetSpecParser {
+
        //public function parse(GadgetId $id, String $xml)
-       public function parse($xml, $id, $prefs)
+       public function parse($xml, $context)
        {
                if (empty($xml)) {
                        throw new SpecParserException("Empty XML document");
@@ -35,28 +35,28 @@
                if (count($doc->ModulePrefs) != 1) {
                        throw new SpecParserException("Missing or duplicated 
<ModulePrefs>");
                }
-               $gadget = new Gadget($id, $prefs);
+               $gadget = new Gadget($context->getGadgetId(), $context);
                // process ModulePref attributes
-               $this->processModulePrefs($id, $gadget, $doc->ModulePrefs);
+               $this->processModulePrefs($gadget, $doc->ModulePrefs);
                // process UserPrefs, if any
-               foreach ( $doc->UserPref as $pref ) {
+               foreach ($doc->UserPref as $pref) {
                        $this->processUserPref($gadget, $pref);
                }
-               foreach ( $doc->Content as $content ) {
+               foreach ($doc->Content as $content) {
                        $this->processContent($gadget, $content);
                }
                //FIXME : should we add an else { throw new 
SpecParserException("Missing <Content> block"); } here ? Java version doesn't 
but it seems like we should ?
-               foreach ( $doc->ModulePrefs->Require as $feature ) {
+               foreach ($doc->ModulePrefs->Require as $feature) {
                        $this->processFeature($gadget, $feature, true);
                }
-               foreach ( $doc->ModulePrefs->Optional as $feature ) {
+               foreach ($doc->ModulePrefs->Optional as $feature) {
                        $this->processFeature($gadget, $feature, false);
                }
                //TODO java version has a todo here for parsing icons
                return $gadget;
        }
-       
-       private function processModulePrefs($id, &$gadget, $ModulePrefs)
+
+       private function processModulePrefs(&$gadget, $ModulePrefs)
        {
                $attributes = $ModulePrefs->attributes();
                if (empty($attributes['title'])) {
@@ -72,12 +72,11 @@
                $gadget->screenshot = isset($attributes['screenshot']) ? 
trim($attributes['screenshot']) : '';
                $gadget->thumbnail = isset($attributes['thumbnail']) ? 
trim($attributes['thumbnail']) : '';
                $gadget->titleUrl = isset($attributes['title_url']) ? 
trim($attributes['title_url']) : '';
-               foreach ( $ModulePrefs->Locale as $locale ) {
+               foreach ($ModulePrefs->Locale as $locale) {
                        $gadget->localeSpecs[] = $this->processLocale($locale);
                }
-       
        }
-       
+
        private function processLocale($locale)
        {
                $attributes = $locale->attributes();
@@ -93,7 +92,7 @@
                $locale->locale = new Locale($languageAttr, $countryAttr);
                return $locale;
        }
-       
+
        private function processUserPref(&$gadget, $pref)
        {
                $attributes = $pref->attributes();
@@ -107,7 +106,7 @@
                $preference->dataType = isset($attributes['datatype']) && 
in_array(strtoupper($attributes['datatype']), $preference->DataTypes) ? 
strtoupper($attributes['datatype']) : 'STRING';
                $preference->defaultValue = isset($attributes['default_value']) 
? trim($attributes['default_value']) : '';
                if (isset($pref->EnumValue)) {
-                       foreach ( $pref->EnumValue as $enum ) {
+                       foreach ($pref->EnumValue as $enum) {
                                $attr = $enum->attributes();
                                // java based shindig doesn't throw an 
exception here, but it -is- invalid and should trigger a parse error
                                if (empty($attr['value'])) {
@@ -120,7 +119,7 @@
                }
                $gadget->userPrefs[] = $preference;
        }
-       
+
        private function processContent(&$gadget, $content)
        {
                $attributes = $content->attributes();
@@ -137,15 +136,15 @@
                        $gadget->contentHref = $url;
                } else {
                        $gadget->contentType = 'HTML';
-                       $html = (string)$content; // no trim here since empty 
lines can have structural meaning, so typecast to string instead
+                       $html = (string) $content; // no trim here since empty 
lines can have structural meaning, so typecast to string instead
                        $view = isset($attributes['view']) ? 
trim($attributes['view']) : '';
                        $views = explode(',', $view);
-                       foreach ( $views as $view ) {
+                       foreach ($views as $view) {
                                $gadget->addContent($view, $html);
                        }
                }
        }
-       
+
        private function processFeature(&$gadget, $feature, $required)
        {
                $featureSpec = new FeatureSpec();
@@ -155,7 +154,7 @@
                }
                $featureSpec->name = trim($attributes['feature']);
                $featureSpec->optional = ! $required;
-               foreach ( $feature->Param as $param ) {
+               foreach ($feature->Param as $param) {
                        $attr = $param->attributes();
                        if (empty($attr['name'])) {
                                throw new SpecParserException("Missing name 
attribute in <Param>.");

Modified: incubator/shindig/trunk/php/gadgets/src/RemoteContent.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/RemoteContent.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/RemoteContent.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/RemoteContent.php Tue Mar 18 
17:29:25 2008
@@ -30,5 +30,5 @@
 }
 
 abstract class RemoteContent {
-       abstract public function fetch($request);
+       abstract public function fetch($request, $context);
 }

Modified: incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php Tue Mar 18 
17:29:25 2008
@@ -18,8 +18,21 @@
  * 
  */
 
+/**
+ * This class serves files from the shindig_root/javascript directory, it was 
created
+ * so that the shindig examples and javascript files would work out of the box 
with
+ * the php version too
+ */
 class FilesServlet extends HttpServlet {
        
+       /**
+        * Handles the get file request, if the file exists and is in the 
correct
+        * location it's echo'd to the browser (with a basic content type 
guessing
+        * based on the file extention, ie .js becomes text/javascript).
+        * If the file location falls outside of the shindig/javascript root a
+        * 400 Bad Request is returned, and if the file is inside of the root
+        * but doesn't exist a 404 error is returned
+        */
        public function doGet()
        {
                global $config;

Modified: 
incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php 
(original)
+++ incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php Tue 
Mar 18 17:29:25 2008
@@ -20,41 +20,43 @@
 
 include ('src/Gadget.php');
 
-define('DEFAULT_VIEW', 'default');
-
+/**
+ * This class deals with the gadget rendering requests (in default config this
+ * would be /gadgets/ifr?url=<some gadget's url>). It uses the gadget server 
and
+ * gadget context to render the xml to a valid html file, and outputs it.
+ * 
+ */
 class GadgetRenderingServlet extends HttpServlet {
-       
+
+       /**
+        * Creates the gadget using the GadgetServer class and calls 
outputGadget
+        *
+        */
        public function doGet()
        {
-               global $config;
                try {
                        if (empty($_GET['url'])) {
                                throw new GadgetException("Missing required 
parameter: url");
                        }
-                       $url = trim($_GET['url']);
-                       $moduleId = isset($_GET['mid']) && 
is_numeric($_GET['mid']) ? intval($_GET['mid']) : 0;
-                       $httpFetcher = new $config['remote_content']();
-                       $view = ! empty($_GET['view']) ? $_GET['view'] : 
DEFAULT_VIEW;
-                       $gadgetId = new GadgetId($url, $moduleId);
-                       $prefs = $this->getPrefsFromRequest();
-                       $locale = $this->getLocaleFromRequest();
-                       $cache = new $config['data_cache']();
-                       // Profiling showed 40% of the processing time was 
spend in the feature registry
-                       // So by caching this and making it a one time 
initialization, we almost double the performance  
-                       if (! ($registry = 
$cache->get(sha1($config['features_path'])))) {
-                               $registry = new 
GadgetFeatureRegistry($config['features_path']);
-                               $cache->set(sha1($config['features_path']), 
$registry);
-                       }
-                       // skipping the contentFilters bit, since there's no 
way to include caja yet
-                       // hopefully a rpc service or command line version will 
be available at some point
+                       // GadgetContext builds up all the contextual variables 
(based on the url or post) 
+                       // plus instances all required classes (feature 
registry, fetcher, blacklist, etc)
+                       $context = new GadgetContext('GADGET');
+                       // Unfortunatly we can't do caja content filtering 
here, hoping we'll have a RPC service
+                       // or command line caja to use for this at some point 
                        $gadgetServer = new GadgetServer();
-                       $gadget = $gadgetServer->processGadget($gadgetId, 
$prefs, $locale, 'GADGET', $httpFetcher, $registry);
-                       $this->outputGadget($gadget, $view);
-               } catch ( Exception $e ) {
+                       $gadget = $gadgetServer->processGadget($context);
+                       $this->outputGadget($gadget, $context);
+               } catch (Exception $e) {
                        $this->outputError($e);
                }
        }
-       
+
+       /**
+        * If an error occured (Exception) this function echo's the Exception's 
message
+        * and if the config['debug'] is true, shows the debug backtrace in a 
div
+        *
+        * @param Exception $e the exception to show
+        */
        private function outputError($e)
        {
                global $config;
@@ -69,33 +71,50 @@
                }
                echo "</body></html>";
        }
-       
+
+       /**
+        * Takes the gadget to output, and depending on its content type calls 
either outputHtml-
+        * or outputUrlGadget
+        *
+        * @param Gadget $gadget gadget to render
+        * @param string $view the view to render (only valid with a html 
content type)
+        */
        private function outputGadget($gadget, $view)
        {
-               switch ( $gadget->getContentType()) {
-                       case 'HTML' :
+               switch ($gadget->getContentType()) {
+                       case 'HTML':
                                $this->outputHtmlGadget($gadget, $view);
                                break;
-                       case 'URL' :
+                       case 'URL':
                                $this->outputUrlGadget($gadget);
                                break;
                }
        }
-       
-       private function outputHtmlGadget($gadget, $view)
+
+       /**
+        * Outputs a html content type gadget.
+        * It creates a html page, with the javascripts from the features 
inline into the page, plus
+        * calls to 'gadgets.config.init' with the syndicator configuration 
(config/syndicator.js) and
+        * 'gadgets.Prefs.setMessages_' with all the substitutions. For 
external javascripts it adds
+        * a <script> tag.
+        *
+        * @param Gadget $gadget
+        * @param GadgetContext $context
+        */
+       private function outputHtmlGadget($gadget, $context)
        {
                global $config;
                $this->setContentType("text/html; charset=UTF-8");
                $output = '';
-               $output .= "<html><head>";
+               $output .= "<html>\n<head>\n";
                // TODO: This is so wrong. (todo copied from java shindig, but 
i would agree with it :))
-               $output .= "<style 
type=\"text/css\">body,td,div,span,p{font-family:arial,sans-serif;} a 
{color:#0000cc;}a:visited {color:#551a8b;}a:active {color:#ff0000;}body{margin: 
0px;padding: 0px;background-color:white;}</style>";
-               $output .= "</head><body>";
+               $output .= "<style 
type=\"text/css\">body,td,div,span,p{font-family:arial,sans-serif;} a 
{color:#0000cc;}a:visited {color:#551a8b;}a:active {color:#ff0000;}body{margin: 
0px;padding: 0px;background-color:white;}</style>\n";
+               $output .= "</head>\n<body>\n";
                $externJs = "";
                $inlineJs = "";
                $externFmt = "<script src=\"%s\"></script>";
-               $forcedLibs = $config['focedJsLibs'];
-               foreach ( $gadget->getJsLibraries() as $library ) {
+               $forcedLibs = $context->getForcedJsLibs();
+               foreach ($gadget->getJsLibraries() as $library) {
                        $type = $library->getType();
                        if ($type == 'URL') {
                                // TODO: This case needs to be handled more 
gracefully by the js
@@ -112,13 +131,12 @@
                        }
                }
                // Forced libs first.
-               //FIXME this doesnt make any sense to me yet, should make it 
actually do something :-)
                if (! empty($forcedLibs)) {
                        $libs = explode(':', $forcedLibs);
                        $output .= sprintf($externFmt, $this->getJsUrl($libs));
                }
                if (strlen($inlineJs) > 0) {
-                       $output .= "<script><!--\n" . $inlineJs . 
"\n-->\n</script>";
+                       $output .= "<script><!--\n" . $inlineJs . 
"\n-->\n</script>\n";
                }
                if (strlen($externJs) > 0) {
                        $output .= $externJs;
@@ -130,28 +148,35 @@
                // remove both /* */ and // style comments, they crash the 
json_decode function
                $contents = preg_replace('/\/\/.*$/m', '', 
preg_replace('@/\\*(?:.|[\\n\\r])*?\\*/@', '', 
file_get_contents($config['syndicator_config'])));
                $syndData = json_decode($contents, true);
-               
+               // build the messages to include in the 
gadgets.Prefs.setMessages_() javascript call
                $msgs = '';
                if ($gadget->getMessageBundle()) {
                        $bundle = $gadget->getMessageBundle();
                        $msgs = json_encode($bundle->getMessages());
                }
-               $output .= "\n<script>\ngadgets.config.init(" . 
json_encode($syndData['gadgets.features']) . 
");\ngadgets.Prefs.setMessages_(".$msgs.");\n</script>\n";
+               // Add the gadget.config.init and gadgets.Prefs.setMessages_ 
calls to the document
+               $output .= "\n<script>\ngadgets.config.init(" . 
json_encode($syndData['gadgets.features']) . ");\ngadgets.Prefs.setMessages_(" 
. $msgs . ");\n</script>\n";
                $gadgetExceptions = array();
-               $content = $gadget->getContentData($view);
+               $content = $gadget->getContentData($context->getView());
                if (empty($content)) {
                        // unknown view
-                       $gadgetExceptions[] = "View: '" . $view . "' invalid 
for gadget: " . $gadget->getId()->getKey();
+                       $gadgetExceptions[] = "View: '" . $context->getView() . 
"' invalid for gadget: " . $gadget->getId()->getKey();
                }
                if (count($gadgetExceptions)) {
                        throw new GadgetException(print_r($gadgetExceptions, 
true));
                }
                $output .= $content . "\n";
-               $output .= "<script>gadgets.util.runOnLoadHandlers();</script>";
-               $output .= "</body></html>";
+               $output .= 
"<script>gadgets.util.runOnLoadHandlers();</script>\n";
+               $output .= "</body>\n</html>";
                echo $output;
        }
-       
+
+       /**
+        * Output's a URL content type gadget, it adds 
libs=<list:of:js:libraries>.js and user preferences
+        * to the href url, and redirects the browser to it
+        *
+        * @param Gadget $gadget
+        */
        private function outputUrlGadget($gadget)
        {
                global $config;
@@ -165,7 +190,7 @@
                $forcedLibs = $config['focedJsLibs'];
                if ($forcedLibs == null) {
                        $reqs = $gadget->getRequires();
-                       foreach ( $reqs as $key => $val ) {
+                       foreach ($reqs as $key => $val) {
                                $libs[] = $key;
                        }
                } else {
@@ -181,7 +206,15 @@
                header('Location: ' . $redirURI);
                die();
        }
-       
+
+       /**
+        * Returns the requested libs (from getjsUrl) with the libs_param_name 
prepended
+        * ie: in libs=core:caja:etc.js format
+        *
+        * @param string $libs the libraries
+        * @param Gadget $gadget
+        * @return string the libs=... string to append to the redirection url
+        */
        private function appendLibsToQuery($libs, $gadget)
        {
                global $config;
@@ -191,12 +224,19 @@
                $ret .= $this->getJsUrl($libs, $gadget);
                return $ret;
        }
-       
+
+       /**
+        * Returns the user preferences in &up_<name>=<val> format
+        *
+        * @param array $libs array of features this gadget requires
+        * @param Gadget $gadget
+        * @return string the up_<name>=<val> string to use in the redirection 
url
+        */
        private function getPrefsQueryString($prefVals)
        {
                global $config;
                $ret = '';
-               foreach ( $prefVals->getPrefs() as $key => $val ) {
+               foreach ($prefVals->getPrefs() as $key => $val) {
                        $ret .= '&';
                        $ret .= $config['userpref_param_prefix'];
                        $ret .= urlencode($key);
@@ -205,16 +245,23 @@
                }
                return $ret;
        }
-       
+
+       /**
+        * generates the library string (core:caja:etc.js) including a checksum 
of all the
+        * javascript content (?v=<sha1 of js) for cache busting
+        *
+        * @param string $libs
+        * @param Gadget $gadget
+        * @return string the list of libraries in core:caja:etc.js?v=checksum> 
format
+        */
        private function getJsUrl($libs, $gadget)
        {
-               global $config;
                $buf = '';
                if (! is_array($libs) || ! count($libs)) {
                        $buf = 'core';
                } else {
                        $firstDone = false;
-                       foreach ( $libs as $lib ) {
+                       foreach ($libs as $lib) {
                                if ($firstDone) {
                                        $buf .= ':';
                                } else {
@@ -226,7 +273,7 @@
                // Build a version string from the sha1() checksum of all 
included javascript
                // to ensure the client always has the right version
                $inlineJs = '';
-               foreach ( $gadget->getJsLibraries() as $library ) {
+               foreach ($gadget->getJsLibraries() as $library) {
                        $type = $library->getType();
                        if ($type != 'URL') {
                                $inlineJs .= $library->getContent() . "\n";
@@ -235,44 +282,4 @@
                $buf .= ".js?v=" . sha1($inlineJs);
                return $buf;
        }
-       
-       // since we don't have a java style request.locale. we create our own
-       // this parses formats like 'en', 'en-us', 'en-us;en-gb' etc
-       //TODO should really verify that this really works with all locale 
strings and that it doesn't trip over priority weight fields
-       private function getLocaleFromRequest()
-       {
-               $language = 'all';
-               $country = 'all';
-               if (! empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
-                       $acceptLanguage = explode(';', 
$_SERVER['HTTP_ACCEPT_LANGUAGE']);
-                       $acceptLanguage = $acceptLanguage[0];
-                       if (strpos($acceptLanguage, '-') !== false) {
-                               $lang = explode('-', $acceptLanguage);
-                               $language = $lang[0];
-                               $country = $lang[1];
-                               if (strpos($country, ',') !== false) {
-                                       $country = explode(',', $country);
-                                       $country = $country[0];
-                               }
-                       } else {
-                               $language = $acceptLanguage;
-                       }
-               
-               }
-               return new Locale($language, $country);
-       }
-       
-       private function getPrefsFromRequest()
-       {
-               global $config;
-               $prefs = array();
-               foreach ( $_GET as $key => $val ) {
-                       if (substr($key, 0, 
strlen($config['userpref_param_prefix'])) == $config['userpref_param_prefix']) {
-                               $name = substr($key, 
strlen($config['userpref_param_prefix']));
-                               $prefs[$name] = $val;
-                       }
-               }
-               return new UserPrefs($prefs);
-       }
-
-}
\ No newline at end of file
+}

Modified: incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php Tue Mar 18 
17:29:25 2008
@@ -23,10 +23,6 @@
  * Mixed with some essentials to make propper http header handling
  * happen in php.
  */
-
-class ServletException extends Exception {
-}
-
 class HttpServlet {
        private $lastModified = false;
        private $contentType = 'text/html';
@@ -34,12 +30,22 @@
        public $noHeaders = false;
        private $noCache = false;
        
+       /**
+        * Enables output buffering so we can do correct header handling in the 
destructor
+        *
+        */
        public function __construct()
        {
                // to do our header magic, we need output buffering on
                ob_start();
        }
        
+       /**
+        * Enter description here...
+        * If noHeaders is false, it adds all the correct http/1.1 headers to 
the request
+        * and deals with modified/expires/e-tags/etc. This makes the server 
behave more like
+        * a real http server.
+        */
        public function __destruct()
        {
                global $config;
@@ -92,40 +98,65 @@
                }
        }
        
+       /**
+        * Sets the content type of this request (forinstance: text/html or 
text/javascript, etc) 
+        *
+        * @param string $type content type header to use
+        */
        public function setContentType($type)
        {
                $this->contentType = $type;
        }
        
+       /**
+        * Returns the current content type 
+        *
+        * @return string content type string
+        */
        public function getContentType()
        {
                return $this->contentType;
        }
        
+       /**
+        * returns the current last modified time stamp
+        *
+        * @return int timestamp
+        */
        public function getLastModified()
        {
                return $this->lastModified;
        }
        
+       /**
+        * Sets the last modified timestamp. It automaticly checks if this 
timestamp
+        * is larger then its current timestamp, and if not ignores the call
+        *
+        * @param int $modified timestamp
+        */
        public function setLastModified($modified)
        {
                $this->lastModified = max($this->lastModified, $modified);
        }
        
+       /**
+        * Sets the noCache boolean. If its set to true, no-caching headers 
will be send
+        * (pragma no cache, expiration in the past)
+        *
+        * @param boolean $cache send no-cache headers?
+        */
        public function setNoCache($cache = false)
        {
                $this->noCache = $cache;
        }
        
+       /**
+        * returns the noCache boolean
+        *
+        * @return boolean
+        */
        public function getNoCache()
        {
                return $this->noCache;
        }
-       
-       public function error($msg)
-       {
-               @ob_end_clean();
-               header("HTTP/1.0 400 Bad Request", true);
-               echo "<html><body><h1>400 - $msg</h1></body></html>";
-       }
-}
\ No newline at end of file
+}

Modified: incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php Tue Mar 18 
17:29:25 2008
@@ -18,8 +18,12 @@
  * 
  */
 
+/**
+ * This event handler deals with the /js/core:caja:etc.js request which 
content type=url gadgets can use
+ * to retrieve our features javascript code
+ */
 class JsServlet extends HttpServlet {
-
+       
        public function doGet()
        {
                global $config;

Modified: incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php Tue Mar 18 
17:29:25 2008
@@ -24,14 +24,28 @@
 // according to features/core/io.js, this is high on the list of things to 
scrap
 define('UNPARSEABLE_CRUFT', "throw 1; < don't be evil' >");
 
+/**
+ * The ProxyHandler class does the actual proxy'ing work. it deals both with
+ * GET and POST based input, and peforms a request based on the input, headers 
and 
+ * httpmethod params. It also deals with request signing and verification thru 
the
+ * authz and st (security token) params. 
+ *
+ */
 class ProxyHandler {
-       private $fetcher;
-       
-       public function __construct($fetcher)
+       private $context;
+
+       public function __construct($context)
        {
-               $this->fetcher = $fetcher;
+               $this->context = $context;
        }
-       
+
+       /**
+        * Fetches content and returns it in JSON format
+        *
+        * @param string $url the url to fetch
+        * @param GadgetSigner $signer the request signer to use
+        * @param string $method the http method to use (get or post) in making 
the request
+        */
        public function fetchJson($url, $signer, $method)
        {
                $token = $this->extractAndValidateToken($signer);
@@ -40,7 +54,7 @@
                // Fetch the content and convert it into JSON.
                // TODO: Fetcher needs to handle variety of HTTP methods.
                $result = $this->fetchContent($signedUrl, $method);
-               $status = (int)$result->getHttpCode();
+               $status = (int) $result->getHttpCode();
                //header("HTTP/1.1 $status", true);
                if ($status == 200) {
                        $output = '';
@@ -57,7 +71,15 @@
                }
                die();
        }
-       
+
+       /**
+        * Fetches the content and returns it as-is using the headers as 
returned
+        * by the remote host.
+        *
+        * @param string $url the url to retrieve
+        * @param GadgetSigner $signer the GadgetSigner to use
+        * @param string $method either get or post
+        */
        public function fetch($url, $signer, $method)
        {
                $token = $this->extractAndValidateToken($signer);
@@ -66,13 +88,14 @@
                //TODO: Fetcher needs to handle variety of HTTP methods.
                $result = $this->fetchContent($signedUrl, $method);
                // TODO: Fetcher needs to handle variety of HTTP methods.
-               $status = (int)$result->getHttpCode();
+               $status = (int) $result->getHttpCode();
                if ($status == 200) {
                        $headers = explode("\n", $result->getResponseHeaders());
-                       foreach ( $headers as $header ) {
+                       foreach ($headers as $header) {
                                if (strpos($header, ':')) {
                                        $key = trim(substr($header, 0, 
strpos($header, ':')));
                                        $val = trim(substr($header, 
strpos($header, ':') + 1));
+                                       // filter out headers that would 
otherwise mess up our output
                                        if (strcasecmp($key, 
"Transfer-Encoding") != 0 && strcasecmp($key, "Cache-Control") != 0 && 
strcasecmp($key, "Expires") != 0 && strcasecmp($key, "Content-Length") != 0) {
                                                header("$key: $val");
                                        }
@@ -90,7 +113,14 @@
                // make sure the HttpServlet destructor doesn't override ours
                die();
        }
-       
+
+       /**
+        * Both fetch and fetchJson call this function to retrieve the actual 
content
+        *
+        * @param string $signedUrl the signed url to fetch
+        * @param string $method either get or post
+        * @return the filled in request (RemoteContentRequest)
+        */
        private function fetchContent($signedUrl, $method)
        {
                //TODO get actual character encoding from the request
@@ -98,8 +128,9 @@
                // Extract the request headers from the $_SERVER super-global 
(this -does- unfortunatly mean that any header that php doesn't understand 
won't be proxied thru though)
                // if this turns out to be a problem we could add support for 
HTTP_RAW_HEADERS, but this depends on a php.ini setting, so i'd rather prevent 
that from being required
                $headers = '';
+               $context = new GadgetContext('GADGET');
                $requestHeaders = $this->request_headers();
-               foreach ( $requestHeaders as $key => $val ) {
+               foreach ($requestHeaders as $key => $val) {
                        if ($key != 'Keep-alive' && $key != 'Connection' && 
$key != 'Host' && $key != 'Accept' && $key != 'Accept-Encoding') {
                                // propper curl header format according to 
http://www.php.net/manual/en/function.curl-setopt.php#80099
                                $headers .= "$key: $val\n";
@@ -114,7 +145,7 @@
                        if ($data) {
                                $data = urldecode($data);
                                $entries = explode('&', $data);
-                               foreach ( $entries as $entry ) {
+                               foreach ($entries as $entry) {
                                        $parts = explode('=', $entry);
                                        // Process only if its a valid 
value=something pair
                                        if (count($parts) == 2) {
@@ -129,27 +160,47 @@
                        // even if postData is an empty string, it will still 
post (since RemoteContentRquest checks if its false)
                        // so the request to POST is still honored
                        $request = new RemoteContentRequest($signedUrl, 
$headers, $postData);
-                       $request = $this->fetcher->fetch($request);
+                       $request = 
$this->context->getHttpFetcher()->fetch($request, $context);
                } else {
                        $request = new RemoteContentRequest($signedUrl, 
$headers);
-                       $request = $this->fetcher->fetch($request);
+                       $request = 
$this->context->getHttpFetcher()->fetch($request, $context);
                }
                return $request;
        }
-       
+
+       /**
+        * Sets the caching headers (overwriting anything the remote host set) 
to force
+        * the browser not to cache this. 
+        *
+        */
        private function setCachingHeaders()
        {
                // TODO: Re-implement caching behavior if appropriate.
                header("Cache-Control: private; max-age=0", true);
                header("Expires: " . gmdate("D, d M Y H:i:s", time() - 3000) . 
" GMT", true);
        }
-       
+
+       /**
+        * Empty function, should make something practical here some day.
+        * it's function should be to validate the given url if its in
+        * correct http(s):port://location/url format
+        *
+        * @param string $url
+        * @return string the 'validated' url
+        */
        private function validateUrl($url)
        {
                //TODO should really make a PHP version of the URI class and 
validate in all the locations the java version does
                return $url;
        }
-       
+
+       /**
+        * Extracts the 'st' token from the GET or POST params and calls the
+        * signer to validate the token
+        *
+        * @param GadgetSigner $signer the signer to use (configured in 
config.php)
+        * @return string the token to use in the signed url
+        */
        private function extractAndValidateToken($signer)
        {
                if ($signer == null) {
@@ -161,7 +212,14 @@
                }
                return $signer->createToken($token);
        }
-       
+
+       /**
+        * Signs a url with the GadgetToken
+        *
+        * @param string $originalUrl
+        * @param GadgetToken $token
+        * @return unknown
+        */
        private function signUrl($originalUrl, $token)
        {
                $authz = isset($_GET['authz']) ? $_GET['authz'] : false;
@@ -177,8 +235,8 @@
                }
                return $token->signUrl($originalUrl, $method);
        }
-       
-       function request_headers()
+
+       private function request_headers()
        {
                // Try to use apache's request headers if available
                if (function_exists("apache_request_headers")) {
@@ -188,7 +246,7 @@
                }
                // if that failed, try to create them from the _SERVER 
superglobal
                $headers = array();
-               foreach ( array_keys($_SERVER) as $skey ) {
+               foreach (array_keys($_SERVER) as $skey) {
                        if (substr($skey, 0, 5) == "HTTP_") {
                                $headername = str_replace(" ", "-", 
ucwords(strtolower(str_replace("_", " ", substr($skey, 0, 5)))));
                                $headers[$headername] = $_SERVER[$skey];

Modified: incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php?rev=638660&r1=638659&r2=638660&view=diff
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php (original)
+++ incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php Tue Mar 18 
17:29:25 2008
@@ -22,36 +22,36 @@
 include_once ("src/http/ProxyHandler.php");
 
 class ProxyServlet extends HttpServlet {
-       
+
        public function doGet()
        {
                global $config;
-               $this->noHeaders = true;        
+               $this->noHeaders = true;
+               $context = new GadgetContext('GADGET');
                // those should be doable in one statement, but php seems to 
still evauluate the second ? and : pair,
                // so throws an error about undefined index on post, even 
though it found it in get ... odd bug 
                $url = isset($_GET['url']) ? $_GET['url'] : false;
-               if (!$url) {
+               if (! $url) {
                        $url = isset($_POST['url']) ? $_POST['url'] : false;
                }
                $url = urldecode($url);
                $method = isset($_GET['httpMethod']) ? $_GET['httpMethod'] : 
false;
-               if (!$method) {
-                       $method = isset($_POST['httpMethod']) ? 
$_POST['httpMethod'] : 'GET'; 
+               if (! $method) {
+                       $method = isset($_POST['httpMethod']) ? 
$_POST['httpMethod'] : 'GET';
                }
-               if (!$url) {
+               if (! $url) {
                        header("HTTP/1.0 400 Bad Request", true);
                        echo "<html><body><h1>400 - Missing url 
parameter</h1></body></html>";
                }
                $gadgetSigner = new $config['gadget_signer']();
-               $httpFetcher = new $config['remote_content']();
-               $proxyHandler = new ProxyHandler($httpFetcher);
+               $proxyHandler = new ProxyHandler($context);
                if (! empty($_GET['output']) && $_GET['output'] == 'js') {
                        $proxyHandler->fetchJson($url, $gadgetSigner, $method);
                } else {
                        $proxyHandler->fetch($url, $gadgetSigner, $method);
                }
        }
-       
+
        public function doPost()
        {
                $this->doGet();


Reply via email to