Changeset 1361

Show
Ignore:
Timestamp:
02/24/08 20:33:42 (4 months ago)
Author:
mikey
Message:

refactored net::stubbles::service::jsonrpc
configuration of services via config/xml/json-rpc-service.xml is no longer supported, one needs to use config/json-rpc-service.ini now
out-of-the-box jsonrpc examples are broken, but this is due to some javascript problems in the example frontend

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/build/stubbles/build.xml

    r1313 r1361  
    4747 
    4848    <mkdir dir="${build.src.dir}/config" /> 
     49    <copy file="${stubbles.base.dir}/config/json-rpc-service.ini" tofile="${build.src.dir}/config/json-rpc-service-dist.ini" /> 
    4950    <copy file="${stubbles.base.dir}/config/xsl-callbacks.ini" tofile="${build.src.dir}/config/xsl-callbacks-dist.ini" /> 
    5051     
     
    6162    <copy file="${stubbles.base.dir}/config/xml/processors.xml" tofile="${build.src.dir}/config/xml/processors-dist.xml" /> 
    6263    <copy file="${stubbles.base.dir}/config/xml/rdbms.xml" tofile="${build.src.dir}/config/xml/rdbms-dist.xml" /> 
    63     <copy file="${stubbles.base.dir}/config/xml/json-rpc-service.xml" tofile="${build.src.dir}/config/xml/json-rpc-service-dist.xml" /> 
    6464    <copy file="${stubbles.base.dir}/config/xml/variantmanager.xml" tofile="${build.src.dir}/config/xml/variantmanager-dist.xml" /> 
    6565 
  • trunk/config/xml/config.xml

    r1242 r1361  
    88  <config name="net.stubbles.ipo.request.class" value="net::stubbles::ipo::request::stubWebRequest" /> 
    99  <config name="net.stubbles.ipo.session.class" value="net::stubbles::ipo::session::stubPHPSession" /> 
    10   <config name="net.stubbles.service.jsonrpc.configfile" value="json-rpc-service.xml" /> 
     10  <config name="net.stubbles.service.jsonrpc.configfile" value="json-rpc-service.ini" /> 
    1111</xj:configuration> 
  • trunk/examples/config/xml/config.xml

    r1219 r1361  
    99  <config name="net.stubbles.ipo.request.class" value="net::stubbles::ipo::request::stubWebRequest" /> 
    1010  <config name="net.stubbles.ipo.session.class" value="net::stubbles::ipo::session::stubPHPSession" /> 
    11   <config name="net.stubbles.service.jsonrpc.configfile" value="json-rpc-service.xml" /> 
     11  <config name="net.stubbles.service.jsonrpc.configfile" value="json-rpc-service.ini" /> 
    1212</xj:configuration> 
  • trunk/examples/docroot/json-rpc/index.php

    r1237 r1361  
    5050  <script type="text/javascript" src="../javascript/json.js"></script> 
    5151  <script type="text/javascript" src="../javascript/stub-base.js"></script> 
     52  <script type="text/javascript"> 
     53    // make sure, that the session id is used for all requests 
     54    stubbles.json.rpc.appendToURL = '&amp;<?php echo $session->getName(); ?>=<?php echo $session->getId(); ?>'; 
     55    stubbles.json.rpc.serviceUrl  = 'jsonrpc.php?processor=jsonrpc'; 
     56  </script> 
    5257  <script type="text/javascript" src="../javascript/stub-json-rpc.js"></script> 
    5358  <script type="text/javascript" src="<?php echo dirname($_SERVER['PHP_SELF']);?>/jsonrpc.php?processor=jsonrpc&amp;__generateProxy=__all"></script> 
     
    6974}; 
    7075var nameServ = new stubbles.json.proxy.NameService(NameCallbackObj); 
    71  
    72 // make sure, that the session id is used for all requests 
    73 stubbles.json.rpc.appendToURL = '&amp;<?php echo $session->getName(); ?>=<?php echo $session->getId(); ?>'; 
    74 stubbles.json.rpc.serviceUrl  = 'jsonrpc.php?processor=jsonrpc'; 
    7576</script> 
    7677</head> 
  • trunk/src/main/php/net/stubbles/service/jsonrpc/stubJsonRpcProcessor.php

    r1301 r1361  
    11<?php 
    22/** 
    3  * JSON-RPC Processor (generic Proxy for Web Services) 
     3 * JSON-RPC processor (generic proxy for web services). 
    44 * 
    55 * @author      Richard Sternagel <richard.sternagel@1und1.de> 
     
    99 * @subpackage  service_jsonrpc 
    1010 */ 
    11 stubClassLoader::load('net::stubbles::ioc::stubBinder', 
    12                       'net::stubbles::lang::stubMode', 
    13                       'net::stubbles::reflection::reflection', 
    14                       'net::stubbles::service::annotations::stubWebMethodAnnotation', 
    15                       'net::stubbles::service::jsonrpc::stubJsonRpcResponse', 
     11stubClassLoader::load('net::stubbles::service::jsonrpc::stubJsonRpcResponse', 
    1612                      'net::stubbles::util::stubRegistry', 
    17                       'net::stubbles::util::validators::stubPassThruValidator', 
    18                       'net::stubbles::util::validators::stubRegexValidator', 
    1913                      'net::stubbles::websites::processors::stubAbstractProcessor' 
    2014); 
    2115/** 
    22  * JSON-RPC Processor (generic Proxy for Web Services) 
     16 * JSON-RPC processor (generic proxy for web services). 
    2317 * 
    2418 * @package     stubbles 
     
    2923{ 
    3024    /** 
    31      * Regexp to validate method param 
     25     * registry key for the service config file 
    3226     */ 
    33     const CLASS_AND_METHOD_PATTERN = '/^([a-zA-Z0-9_]+\.[a-zA-Z0-9_]+)$/'; 
     27    const KEY_SERVICE_FILE = 'net.stubbles.service.jsonrpc.configfile'; 
    3428    /** 
    35      * Regexp to validate param param 
     29     * configuration file with list of client classes 
     30     * 
     31     * @var  string 
    3632     */ 
    37     const PARAM_PATTERN            = '/^[a-zA-Z0-9_]+$/'; 
    38     /** 
    39      * Regexp to validate id param 
    40      */ 
    41     const ID_PATTERN               = '/^\d{6,7}$/'; 
    42     /** 
    43      * Registry key for the service config file 
    44      */ 
    45     const KEY_SERVICE_FILE         = 'net.stubbles.service.jsonrpc.configfile'; 
    46     /** 
    47      * Map client classes to fully qualified class names 
    48      * 
    49      * @var  array<string,array<string,string>> 
    50      */ 
    51     protected $classMap            = array(); 
    52     /** 
    53      * Configuration of the service 
    54      * 
    55      * @var  array<string,mixed> 
    56      */ 
    57     protected $serviceConfig       = array(); 
     33    protected $configFile; 
    5834 
    5935    /** 
     
    6945        $response = new stubJsonRpcResponse($response); 
    7046        parent::__construct($request, $session, $response, $pageFactory); 
     47        $this->configFile = stubConfig::getConfigPath() . DIRECTORY_SEPARATOR . stubRegistry::getConfig(self::KEY_SERVICE_FILE, 'json-rpc-service.ini'); 
    7148    } 
    7249 
    7350    /** 
    74      * Process the request 
     51     * processes the request 
    7552     * 
    76      * This method only dispatches the request to different methods. 
     53     * This method only dispatches the request to different subprocessors. 
    7754     *  
    7855     * @return  stubAbstractProcessor 
     
    8057    public function process() 
    8158    { 
    82         $this->loadServiceConfig($this->getServiceFilePath()); 
    83  
    84         if ($this->request->hasValue('__generateProxy') === true) { 
    85             $proxyClassvalidator = new stubRegexValidator('/^[A-Za-z,0-9_\.]+$/'); 
    86             $classes = $this->request->getValidatedValue($proxyClassvalidator, '__generateProxy', stubRequest::SOURCE_PARAM); 
    87             if ('__all' === $classes) { 
    88                 $this->generateProxies(); 
    89             } else { 
    90                 $this->generateProxies(explode(',', $classes)); 
    91             } 
    92         } elseif ($this->request->hasValue('__smd') === true) { 
    93             $smdClassvalidator = new stubRegexValidator('/^[A-Za-z0-9_\.]+$/'); 
    94             $class = $this->request->getValidatedValue($smdClassvalidator, '__smd', stubRequest::SOURCE_PARAM); 
    95             $this->generateSmd($class); 
    96         } elseif ($this->request->getMethod() === 'post') { 
    97             $this->processPostRequest(); 
    98         } else { 
    99             $this->processGetRequest(); 
     59        $fqClassName = $this->getSubProcessorClassName(); 
     60        $nqClassName = stubClassLoader::getNonQualifiedClassName($fqClassName); 
     61        if (class_exists($nqClassName, false) === false) { 
     62            stubClassLoader::load($fqClassName); 
    10063        } 
    10164         
     65        $subProcessor = new $nqClassName(); 
     66        $subProcessor->process($this->request, $this->session, $this->response, $this->loadClassMap()); 
    10267        return $this; 
    10368    } 
    10469 
    10570    /** 
    106      * Get the full path to the config file describing the services 
     71     * loads the class map 
    10772     * 
    108      * @return  string 
     73     * @return  array<string,string> 
    10974     * @throws  stubFileNotFoundException 
    11075     */ 
    111     protected function getServiceFilePath() 
     76    protected function loadClassMap() 
    11277    { 
    113         $configFile = stubConfig::getConfigPath() . '/xml/' . stubRegistry::getConfig(self::KEY_SERVICE_FILE, 'json-rpc-service.xml'); 
    114         if (file_exists($configFile) === false || is_readable($configFile) === false) { 
     78        if (file_exists($this->configFile) === false || is_readable($this->configFile) === false) { 
    11579            stubClassLoader::load('net::stubbles::lang::exceptions::stubFileNotFoundException'); 
    116             throw new stubFileNotFoundException($configFile); 
     80            throw new stubFileNotFoundException($this->configFile); 
    11781        } 
    118  
    119         return $configFile
     82         
     83        return parse_ini_file($this->configFile)
    12084    } 
    12185 
    12286    /** 
    123      * Load the service configuration file 
     87     * returns the subprocessor class to be used 
    12488     * 
    125      * @param  string  $serviceConfigFile 
     89     * @return  string 
    12690     */ 
    127     protected function loadServiceConfig($serviceConfigFile
     91    protected function getSubProcessorClassName(
    12892    { 
    129         $cacheFile = stubConfig::getCachePath() . '/jsonrpc_' . md5($serviceConfigFile) . '.cache'; 
    130         if (file_exists($cacheFile) === true) { 
    131             $cacheData = unserialize(file_get_contents($cacheFile)); 
    132             $this->classMap      = $cacheData['classMap']
    133             $this->serviceConfig = $cacheData['serviceConfig']; 
    134             return
     93        if ($this->request->getMethod() === 'post') { 
     94            return 'net::stubbles::service::jsonrpc::subprocessors::stubJsonRpcPostSubProcessor'; 
     95        } elseif ($this->request->hasValue('__generateProxy') === true) { 
     96            return 'net::stubbles::service::jsonrpc::subprocessors::stubJsonRpcGenerateProxiesSubProcessor'
     97        } elseif ($this->request->hasValue('__smd') === true) { 
     98            return 'net::stubbles::service::jsonrpc::subprocessors::stubJsonRpcGenerateSmdSubProcessor'
    13599        } 
    136100 
    137         stubClassLoader::load('net::stubbles::util::xjconf::xjconf', 
    138                               'net::stubbles::util::xjconf::xjconfReal'); 
    139  
    140         $xjconf = new stubXJConfFacade(new XJConfFacade(array('__default' => stubXJConfLoader::getInstance()))); 
    141         $xjconf->addDefinitions(stubFactory::getResourceURIs('xjconf/json-rpc-service.xml')); 
    142         $xjconf->enableXIncludes(); 
    143         $xjconf->parse($serviceConfigFile); 
    144         $this->classMap = $xjconf->getConfigValue('services'); 
    145         $cacheData      = array('classMap'      => $this->classMap, 
    146                                 'serviceConfig' => $this->serviceConfig 
    147                           ); 
    148         file_put_contents($cacheFile, serialize($cacheData)); 
    149     } 
    150  
    151     /** 
    152      * Generate and send the generated javascript clients 
    153      * 
    154      * @param  array   $classes      optional  restrict to this list of classes 
    155      * @param  string  $jsNamespace  optional  custom javascript namespace 
    156      */ 
    157     public function generateProxies($classes = null, $jsNamespace = 'stubbles.json.proxy') 
    158     { 
    159         stubClassLoader::load('net::stubbles::service::jsonrpc::util::stubJsonRpcProxyGenerator'); 
    160         $tmp        = parse_url($this->request->getURI()); 
    161         $serviceUrl = '//' . $tmp['path']; 
    162         if ($this->request->hasValue('processor')) { 
    163             $processor   = $this->request->getValidatedValue(new stubPassThruValidator(), 'processor', stubRequest::SOURCE_PARAM); 
    164             $serviceUrl .= '?processor='.$processor; 
    165         } 
    166  
    167         $this->response->write($jsNamespace . " = {};\n\n"); 
    168         $generator = new stubJsonRpcProxyGenerator($serviceUrl); 
    169         foreach ($this->classMap as $jsClass => $serviceConfig) { 
    170             if (is_array($classes) === true && in_array($jsClass, $classes) === false) { 
    171                 continue; 
    172             } 
    173  
    174             try { 
    175                 $this->response->write($generator->generateJavascriptProxy($serviceConfig['className'], $jsClass)); 
    176             } catch (Exception $e) { 
    177                 if (stubMode::$CURRENT->name() !== 'PROD') { 
    178                     $this->response->write("console.error('Generation of proxy for {$serviceConfig['className']} failed.');\n"); 
    179                     $this->response->write($this->convertStringToFirebug($e->__toString())); 
    180                 } 
    181             } 
    182         } 
    183     } 
    184  
    185     /** 
    186      * Generate and send SMD for the specified class 
    187      * 
    188      * @param  string  $class 
    189      */ 
    190     public function generateSmd($class) 
    191     { 
    192         stubClassLoader::load('net::stubbles::service::jsonrpc::util::stubSmdGenerator'); 
    193         $tmp        = parse_url($this->request->getURI()); 
    194         $serviceUrl = '//' . $tmp['path']; 
    195         if ($this->request->hasValue('processor') === true) { 
    196             $processor   = $this->request->getValidatedValue(new stubPassThruValidator(), 'processor', stubRequest::SOURCE_PARAM); 
    197             $serviceUrl .= '?processor=' . $processor; 
    198             $serviceUrl .= '&__class=' . $class; 
    199         } 
    200         $generator = new stubSmdGenerator($serviceUrl); 
    201         // get rid of namespace for class matching 
    202         $class = preg_replace('/stubbles\.json\.proxy\./', '', $class); 
    203         $classInfo = $this->classMap[$class]; 
    204         try { 
    205             $this->response->write($generator->generateSmd($classInfo['className'], $class)); 
    206         } catch (Exception $e) { 
    207             if (stubMode::$CURRENT->name() !== 'PROD') { 
    208                 $this->response->write("console.error('Generation of SMD for {$classInfo['className']} failed.');\n"); 
    209                 $this->response->write($this->convertStringToFirebug($e->__toString())); 
    210             } 
    211         } 
    212     } 
    213  
    214  
    215     /** 
    216      * Converts any string to Javascript code that writes 
    217      * messages to the firebug console 
    218      * 
    219      * @param   string  $string  the message to output to the console 
    220      * @param   string  $level   level of the message 
    221      * @return  string 
    222      */ 
    223     protected function convertStringToFirebug($string, $level = 'error') 
    224     { 
    225         $result = ''; 
    226         $lines  = explode("\n", $string); 
    227         foreach ($lines as $line) { 
    228             $result .= "console.{$level}('" . addslashes($line) . "');\n"; 
    229         } 
    230  
    231         return $result; 
    232     } 
    233  
    234     /** 
    235      * Handle a JSON-RPC POST request 
    236      * 
    237      * @throws  stubException 
    238      */ 
    239     public function processPostRequest() 
    240     { 
    241         $requestJsonObj = $this->request->getValidatedRawData(new stubPassThruValidator()); 
    242         $phpJsonObj     = json_decode($requestJsonObj); 
    243         if (is_object($phpJsonObj) === false) { 
    244             $this->response->writeFault(null, 'Invalid request.'); 
    245             return; 
    246         } 
    247  
    248         if (isset($phpJsonObj->id) === false) { 
    249             $this->response->writeFault(null, 'Invalid request: No id given.'); 
    250             return; 
    251         } 
    252  
    253         if (isset($phpJsonObj->method) === false) { 
    254             $this->response->writeFault($phpJsonObj->id, 'Invalid request: No method given.'); 
    255             return; 
    256         } 
    257  
    258         if (isset($phpJsonObj->params) === false) { 
    259             $this->response->writeFault($phpJsonObj->id, 'Invalid request: No params given.'); 
    260             return; 
    261         } 
    262  
    263         try { 
    264             $className = null; 
    265             if ($this->request->hasValue('__class') === true) { 
    266                 $className = $this->request->getValidatedValue(new stubPassThruValidator(), '__class'); 
    267             } 
    268             $reflect = $this->getClassAndMethod($phpJsonObj->method, $className); 
    269             $result  = $this->invokeServiceMethod($reflect['class'], $reflect['method'], $phpJsonObj->params); 
    270             $this->response->writeResponse($phpJsonObj->id, $result); 
    271         } catch (Exception $e) { 
    272             $this->response->writeFault($phpJsonObj->id, $e->getMessage()); 
    273         } 
    274     } 
    275  
    276     /** 
    277      * Handle a JSON-RPC GET request 
    278      * 
    279      * This is mainly used for debugging purposes. 
    280      * 
    281      * http://localhost/stubbles/docroot/json.php? 
    282      * <paramName>=2 
    283      * [&<paramName>=3]* 
    284      * &method=<classname>.<methodname> 
    285      * &id=186252 
    286      */ 
    287     public function processGetRequest() 
    288     { 
    289         try { 
    290             $idPattern = new stubRegexValidator(self::ID_PATTERN); 
    291             $requestId = $this->request->getValidatedValue($idPattern, 'id'); 
    292             $reflect   = $this->getClassAndMethod($this->request->getValidatedValue(new stubPassThruValidator(), 'method')); 
    293             $params    = $this->retrieveGETParams($reflect['method']); 
    294             $result    = $this->invokeServiceMethod($reflect['class'], $reflect['method'], $params); 
    295             $this->response->writeResponse($requestId, $result); 
    296         } catch (Exception $e) { 
    297             $this->response->writeFault($requestId, $e->getMessage()); 
    298         } 
    299     } 
    300  
    301     /** 
    302      * creates the method to call 
    303      * 
    304      * @param   string  $methodName 
    305      * @param   string  $className  optional, if used with dojo's SMD 
    306      * @return  array 
    307      * @throws  stubException 
    308      */ 
    309     protected function getClassAndMethod($methodName, $className = null) 
    310     { 
    311         if (null === $className) { 
    312             if (!preg_match(self::CLASS_AND_METHOD_PATTERN, $methodName)) { 
    313                 throw new stubException('Invalid request: method-Pattern has to be <className>.<methodName>.'); 
    314             } 
    315  
    316             list($className, $methodName) = explode('.', $methodName); 
    317         } 
    318         if (isset($this->classMap[$className]) === false) { 
    319             throw new stubException('Unknown class ' . $className . '.'); 
    320         } 
    321  
    322         $clazz = new stubReflectionClass($this->classMap[$className]['className']); 
    323         if ($clazz->hasMethod($methodName) === false) { 
    324             throw new stubException('Unknown method ' . $className . '.' . $methodName . '.'); 
    325         } 
    326  
    327         $method = $clazz->getMethod($methodName); 
    328         if ($method->hasAnnotation('WebMethod') === false) { 
    329             throw new stubException('Method ' . $className . '.' . $methodName . ' is no WebMethod.'); 
    330         } 
    331  
    332         return array('class' => $clazz, 'method' => $method); 
    333     } 
    334  
    335     /** 
    336      * Invoke the requested methods 
    337      * 
    338      * @param   stubReflectionClass   $class 
    339      * @param   stubReflectionMethod  $method 
    340      * @param   array                 $params 
    341      * @return  mixed 
    342      * @throws  stubRuntimeException 
    343      * @throws  stubException 
    344      */ 
    345     protected function invokeServiceMethod(stubReflectionClass $class, stubReflectionMethod $method, $params) 
    346     { 
    347         if ($method->getNumberOfRequiredParameters() > count($params)) { 
    348             throw new stubException('Invalid amount of parameters passed.'); 
    349         } 
    350  
    351         $binder = stubRegistry::get(stubBinder::REGISTRY_KEY); 
    352         if (($binder instanceof stubBinder) === false) { 
    353             throw new stubRuntimeException('No instance of net::stubbles::ioc::stubBinder in registry.'); 
    354         } 
    355  
    356         $instance = $binder->getInjector()->getInstance($class->getName()); 
    357         return $method->invokeArgs($instance, $params); 
    358     } 
    359  
    360     /** 
    361      * Get the parameters from the GET request 
    362      * 
    363      * @param   stubReflectionMethod  $method 
    364      * @return  array 
    365      * @throws  stubException 
    366      */ 
    367     protected function retrieveGETParams(stubReflectionMethod $method) 
    368     { 
    369         $paramPattern = new stubRegexValidator(self::PARAM_PATTERN); 
    370         $paramValues  = array(); 
    371         foreach ($method->getParameters() as $param) { 
    372             $paramName  = $param->getName(); 
    373             $paramValue = $this->request->getValidatedValue($paramPattern, $paramName); 
    374             if (null === $paramValue) { 
    375                 throw new stubException('Param '. $paramName . ' is missing.'); 
    376             } 
    377  
    378             array_push($paramValues, $paramValue); 
    379         } 
    380  
    381         return $paramValues; 
     101        return 'net::stubbles::service::jsonrpc::subprocessors::stubJsonRpcGetSubProcessor'; 
    382102    } 
    383103} 
  • trunk/src/main/php/net/stubbles/service/jsonrpc/stubJsonRpcResponse.php

    r1301 r1361  
    3232     * static initializing 
    3333     */ 
     34    // @codeCoverageIgnoreStart 
    3435    public static function __static() 
    3536    { 
    3637        self::$encoder = new stubRecursiveStringEncoder(new stubUTF8Encoder()); 
    3738    } 
     39    // @codeCoverageIgnoreEnd 
    3840 
    3941    /** 
  • trunk/src/main/php/net/stubbles/service/jsonrpc/util/stubJsonRpcProxyGenerator.php

    r1301 r1361  
    2323     * 
    2424     * @param   string  $className    name of the class to generate the proxy from 
    25      * @param   string  $jsClass      name of the generated javascript proxy 
    26      * @param   string  $jsNamespace  optional custom javascript namespace 
     25     * @param   string  $jsClass      optional  name of the generated javascript proxy 
     26     * @param   string  $jsNamespace  optional custom javascript namespace 
    2727     * @return  string 
    2828     * @throws  stubClassNotFoundException 
     
    3131    { 
    3232        $clazz = new stubReflectionClass($className); 
    33         if ($jsClass == null) { 
     33        if (null === $jsClass) { 
    3434            $jsClass = $clazz->getName(); 
    3535        } 
     
    4040 
    4141        foreach ($clazz->getMethods() as $method) { 
    42             if (!$method->hasAnnotation('WebMethod')) { 
    43                 continue; 
     42            if ($method->hasAnnotation('WebMethod') === true) { 
     43                $methodName = $method->getName(); 
     44                $jsCode    .= "{$jsNamespace}.{$jsClass}.prototype.{$methodName} = function() {\n"; 
     45                $jsCode    .= "    return this.dispatcher.doCall('{$jsClass}.{$methodName}', arguments);\n"; 
     46                $jsCode    .= "};\n"; 
    4447            } 
    45  
    46             $methodName = $method->getName(); 
    47             $jsCode .= "{$jsNamespace}.{$jsClass}.prototype.{$methodName} = function() {\n"; 
    48             $jsCode .= "    return this.dispatcher.doCall('{$jsClass}.{$methodName}', arguments);\n"; 
    49             $jsCode .= "};\n"; 
    5048        } 
     49         
    5150        return $jsCode; 
    5251    } 
  • trunk/src/main/php/net/stubbles/service/jsonrpc/util/stubSmdGenerator.php

    r1226 r1361  
    11<?php 
    22/** 
    3  * Class to generate service method descriptions 
    4  * for JSON-RPC proxies. 
     3 * Class to generate service method descriptions for JSON-RPC proxies. 
    54 * 
    65 * @author      Stephan Schmidt <schst@stubbles.net> 
     6 * @author      Frank Kleine <mikey@stubbles.net> 
    77 * @package     stubbles 
    88 * @subpackage  service_jsonrpc_util 
     
    1212); 
    1313/** 
    14  * Class to generate service method descriptions 
    15  * for JSON-RPC proxies. 
     14 * Class to generate service method descriptions for JSON-RPC proxies. 
    1615 * 
    1716 * @package     stubbles 
     
    4140     * 
    4241     * @param   string  $className  name of the class to generate the proxy from 
    43      * @param   string  $jsClass    name of the generated javascript proxy 
     42     * @param   string  $jsClass    optional  name of the generated javascript proxy 
    4443     * @return  string 
    45      * @throws  stubClassNotFoundException 
    4644     */ 
    4745    public function generateSmd($className, $jsClass = null) 
     
    5250        $smdData->serviceURL  = $this->serviceURL; 
    5351        $smdData->methods     = array(); 
    54  
    55         $clazz = new stubReflectionClass($className); 
    56         if ($jsClass !== null) { 
     52        if (null !== $jsClass) { 
    5753            $smdData->objectName = $jsClass; 
    5854        } 
    5955 
     56        $clazz = new stubReflectionClass($className); 
    6057        foreach ($clazz->getMethods() as $method) { 
    61             if (!$method->hasAnnotation('WebMethod')) { 
    62                 continue; 
    63             } 
    64  
    65             $methodDef = new stdClass(); 
    66             $methodDef->name       = $method->getName(); 
    67             $methodDef->parameters = array(); 
    68             $smdData->methods[] = $methodDef; 
    69  
    70             foreach ($method->getParameters() as $parameter) { 
    71                 $paramDef = new stdClass(); 
    72                 $paramDef->name = $parameter->getName(); 
    73                 $methodDef->parameters[] = $paramDef; 
     58            if ($method->hasAnnotation('WebMethod') === true) { 
     59                $methodDef             = new stdClass(); 
     60                $methodDef->name       = $method->getName(); 
     61                $methodDef->parameters = array(); 
     62                $smdData->methods[]    = $methodDef; 
     63                foreach ($method->getParameters() as $parameter) { 
     64                    $paramDef = new stdClass(); 
     65                    $paramDef->name = $parameter->getName(); 
     66                    $methodDef->parameters[] = $paramDef; 
     67                } 
    7468            } 
    7569        } 
     70         
    7671        return json_encode($smdData); 
    7772    } 
  • trunk/src/main/php/org/stubbles/phing/tasks/stubGenerateJsonRpcProxiesTask.php

    r1221 r1361  
    11<?php 
    22/** 
    3  * Task to generate JSON-RPC proxies 
     3 * Task to generate JSON-RPC proxies. 
    44 * 
    55 * @author      Stephan Schmidt <schst@stubbles.net> 
     6 * @author      Frank Kleine <mikey@stubbles.net> 
    67 * @package     stubbles 
    78 * @subpackage  phing_tasks 
    89 */ 
    9  
    1010/** 
    1111 * Uses the Phing Task 
    1212 */ 
    1313require_once 'phing/Task.php'; 
    14  
    1514/** 
    16  * Task to generate JSON-RPC proxies 
     15 * Task to generate JSON-RPC proxies. 
    1716 * 
    1817 * @author      Stephan Schmidt <schst@stubbles.net> 
     
    4847     * @param string $targetFolder 
    4948     */ 
    50     public function setTargetFolder($targetFolder) { 
     49    public function setTargetFolder($targetFolder) 
     50    { 
    5151        $this->targetFolder = $targetFolder; 
    5252    } 
     
    5757     * @param string $serviceFile 
    5858     */ 
    59     public function setServiceFile($serviceFile) { 
     59    public function setServiceFile($serviceFile) 
     60    { 
    6061        $this->serviceFile = $serviceFile; 
    6162    } 
     
    6768     * @param string $namespace 
    6869     */ 
    69     public function setJavaScriptNamespace($namespace) { 
     70    public function setJavaScriptNamespace($namespace) 
     71    { 
    7072        $this->javaScriptNamespace = $namespace; 
    7173    } 
     
    8486    public function main() 
    8587    { 
    86         stubClassLoader::load('net::stubbles::util::xjconf::xjconf', 
    87                               'net::stubbles::util::xjconf::xjconfReal', 
    88                               'net::stubbles::service::jsonrpc::util::stubJsonRpcProxyGenerator'); 
    89  
    90         $xjconf = new stubXJConfFacade(new XJConfFacade(array('__default' => stubXJConfLoader::getInstance()))); 
    91         $xjconf->addDefinitions(stubFactory::getResourceURIs('xjconf/json-rpc-service.xml')); 
    92         $xjconf->enableXIncludes(); 
    93         $configFile = stubConfig::getConfigPath() . '/xml/json-rpc-service.xml'; 
    94         $xjconf->parse($configFile); 
    95  
    96         $services = $xjconf->getConfigValue('services'); 
    97         $generator = new stubJsonRpcProxyGenerator(); 
    98          
     88        stubClassLoader::load('net::stubbles::service::jsonrpc::util::stubJsonRpcProxyGenerator'); 
     89        $services   = parse_ini_file(stubConfig::getConfigPath() . '/json-rpc-service.init') 
     90        $generator  = new stubJsonRpcProxyGenerator(); 
    9991        $fullJsCode = "{$this->javaScriptNamespace} = {};\n\n"; 
    100         foreach ($services as $serviceConfig) { 
     92        foreach ($services as $class => $fqClassName) { 
    10193            try { 
    102                 $jsCode = $generator->generateJavascriptProxy($serviceConfig['className'], $serviceConfig['name'], $this->javaScriptNamespace); 
     94                $jsCode = $generator->generateJavascriptProxy($fqClassName, $class, $this->javaScriptNamespace); 
    10395            } catch (stubClassNotFoundException $e) { 
    104                 $this->log("Cannot generate proxy for {$serviceConfig['className']}, class does not exist.", Project::MSG_ERR); 
    105                 throw new BuildException("Cannot generate proxy for {$serviceConfig['className']}, class does not exist."); 
     96                $this->log("Cannot generate proxy for {$fqClassName}, class does not exist.", Project::MSG_ERR); 
     97                throw new BuildException("Cannot generate proxy for {$fqClassName}, class does not exist."); 
    10698            } 
    107             $targetFile = $this->targetFolder . '/' . $serviceConfig['name'] . '.js'; 
     99             
     100            $targetFile = $this->targetFolder . '/' . $class . '.js'; 
    108101            if (@file_put_contents($targetFile, $jsCode)) {; 
    109                 $this->log("Wrote proxy for {$serviceConfig['className']} to {$targetFile}."); 
     102                $this->log("Wrote proxy for {$fqClassName} to {$targetFile}."); 
    110103            } else { 
    111                 $this->log("Cannot write proxy for {$serviceConfig['className']} to {$targetFile}.", Project::MSG_ERR); 
     104                $this->log("Cannot write proxy for {$fqClassName} to {$targetFile}.", Project::MSG_ERR); 
    112105                throw new BuildException("Cannot write proxy classes to {$targetFile}."); 
    113106            } 
     107             
    114108            $fullJsCode .= $jsCode; 
    115109        } 
     110         
    116111        if (empty($jsCode)) { 
    117112            return; 
    118113        } 
     114         
    119115        $targetFile = $this->targetFolder . '/allClients.js'; 
    120116        if (@file_put_contents($targetFile, $fullJsCode)) {; 
  • trunk/src/main/resources/phing/build-stubbles.xml

    r1237 r1361  
    6767        <append destFile="build.properties" text="jsonrpc.clients.dir=${jsonrpc.clients.dir}${line.separator}"/> 
    6868        <append destFile="build.properties" text="jsonrpc.clients.ns=${jsonrpc.clients.ns}${line.separator}"/> 
    69         <copy file="${stubbles.config.path}/xml/json-rpc-service-dist.xml" tofile="${stubbles.config.path}/xml/json-rpc-service.xml" overwrite="true"> 
     69        <copy file="${stubbles.config.path}/json-rpc-service-dist.ini" tofile="${stubbles.config.path}/json-rpc-service.ini" overwrite="true"> 
    7070          <filterchain> 
    7171            <expandproperties /> 
     
    257257      <then> 
    258258        <if> 
    259           <available file="${project.basedir}/config/xml/json-rpc-service.xml"/> 
     259          <available file="${project.basedir}/config/json-rpc-service.ini"/> 
    260260          <then> 
    261261            <mkdir dir="${project.basedir}/docroot/${jsonrpc.clients.dir}"/> 
    262             <stubGenerateJsonRpcProxies serviceFile="${project.basedir}/config/xml/json-rpc-service.xml
     262            <stubGenerateJsonRpcProxies serviceFile="${project.basedir}/config/json-rpc-service.ini
    263263                                        targetFolder="${project.basedir}/docroot/${jsonrpc.clients.dir}" 
    264264                                        javaScriptNamespace="${jsonrpc.clients.ns}"/> 
    265265          </then> 
    266266          <else> 
    267             <echo>No json-rpc-service.xml configuration file available.</echo> 
     267            <echo>No json-rpc-service.ini configuration file available.</echo> 
    268268            <echo>Skipping JSON-RPC client generation.</echo> 
    269269          </else> 
  • trunk/src/test/php/net/stubbles/service/ServiceTestSuite.php

    r1303 r1361  
    2929        $suite->addTestFile($dir . '/jsonrpc/stubJsonRpcProcessorTestCase.php'); 
    3030        $suite->addTestFile($dir . '/jsonrpc/stubJsonRpcResponseTestCase.php'); 
     31        $suite->addTestFile($dir . '/jsonrpc/subprocessors/stubJsonRpcAbstractGenerateSubProcessorTestCase.php'); 
     32        $suite->addTestFile($dir . '/jsonrpc/subprocessors/stubJsonRpcGenerateProxiesSubProcessorTestCase.php'); 
     33        $suite->addTestFile($dir . '/jsonrpc/subprocessors/stubJsonRpcGenerateSmdSubProcessorTestCase.php'); 
     34        $suite->addTestFile($dir . '/jsonrpc/subprocessors/stubJsonRpcGetSubProcessorTestCase.php'); 
     35        $suite->addTestFile($dir . '/jsonrpc/subprocessors/stubJsonRpcPostSubProcessorTestCase.php'); 
     36        $suite->addTestFile($dir . '/jsonrpc/util/stubFirebugEncoderTestCase.php'); 
    3137        $suite->addTestFile($dir . '/jsonrpc/util/stubJsonRpcProxyGeneratorTestCase.php'); 
     38        $suite->addTestFile($dir . '/jsonrpc/util/stubSmdGeneratorTestCase.php'); 
    3239         
    3340        // soap 
  • trunk/src/test/php/net/stubbles/service/jsonrpc/stubJsonRpcProcessorTestCase.php

    r1303 r1361  
    33 * Test for net::stubbles::service::jsonrpc::stubJsonRpcProcessor. 
    44 * 
    5  * @author          Richard Sternagel 
    6  * @author          Stephan Schmidt <schst@stubbles.net> 
    7  * @package         stubbles 
    8  * @subpackage      service_jsonrpc_test 
     5 * @author      Richard Sternagel 
     6 * @author      Stephan Schmidt <schst@stubbles.net> 
     7 * @author      Frank Kleine <mikey@stubbles.net> 
     8 * @package     stubbles 
     9 * @subpackage  service_jsonrpc_test 
    910 */ 
    10 stubClassLoader::load('net::stubbles::service::jsonrpc::stubJsonRpcProcessor'); 
     11stubClassLoader::load('net::stubbles::service::jsonrpc::stubJsonRpcProcessor', 
     12                      'net::stubbles::service::jsonrpc::subprocessors::stubJsonRpcSubProcessor' 
     13); 
     14@include_once 'vfsStream/vfsStream.php'; 
    1115/** 
    12  * Test service 
     16 * Helper class for the test. 
    1317 * 
     18 * @author      Frank Kleine <mikey@stubbles.net> 
    1419 * @package     stubbles 
    1520 * @subpackage  service_jsonrpc_test 
     
    1823{ 
    1924    /** 
    20      * sets the class map 
    21      * 
    22      * @param  array<string,array<string,string>>  $classMap 
    23      */ 
    24     public function setClassMap(array $classMap) 
    25     { 
    26         $this->classMap = $classMap; 
    27     } 
    28 
    29 /** 
    30  * Test service 
    31  * 
    32  * @package     stubbles 
    33  * @subpackage  service_jsonrpc_test 
    34  */ 
    35 class TestService extends stubBaseObject 
    36 
    37     /** 
    38      * test method for web service 
    39      * 
    40      * @param   int  $a 
    41      * @param   int  $b 
    42      * @return  int 
    43      * @WebMethod 
    44      */ 
    45     public function add($a, $b) 
    46     { 
    47         return ($a + $b); 
    48     } 
    49  
    50     /** 
    51      * another method that is not marked as WebMethod 
    52      * 
    53      * @param   int  $a 
    54      * @param   int  $b 
    55      * @return  int 
    56      */ 
    57     public function mod($a, $b) 
    58     { 
    59         return ($a % $b); 
     25     * sets the config file to be used 
     26     * 
     27     * @param  string  $configFile 
     28     */ 
     29    public function setConfigFile($configFile) 
     30    { 
     31        $this->configFile = $configFile; 
     32    } 
     33 
     34    /** 
     35     * access to protected class map loading 
     36     * 
     37     * @return  array<string,string> 
     38     */ 
     39    public function callLoadClassMap() 
     40    { 
     41        return $this->loadClassMap();