From 2328401632cd114cf96d694db12d0ce4823777b6 Mon Sep 17 00:00:00 2001 From: Bui Sy Nguyen Date: Fri, 22 Jan 2016 14:49:22 +0700 Subject: [PATCH] Implement #6: add 'discovery' package --- fproject/amf/discovery/ClassFindInfo.php | 55 ++++++ fproject/amf/discovery/MethodDescriptor.php | 70 +++++++ .../amf/discovery/ParameterDescriptor.php | 54 ++++++ fproject/amf/discovery/ServiceDescriptor.php | 59 ++++++ fproject/amf/discovery/ServiceRouter.php | 178 ++++++++++++++++++ 5 files changed, 416 insertions(+) create mode 100644 fproject/amf/discovery/ClassFindInfo.php create mode 100644 fproject/amf/discovery/MethodDescriptor.php create mode 100644 fproject/amf/discovery/ParameterDescriptor.php create mode 100644 fproject/amf/discovery/ServiceDescriptor.php create mode 100644 fproject/amf/discovery/ServiceRouter.php diff --git a/fproject/amf/discovery/ClassFindInfo.php b/fproject/amf/discovery/ClassFindInfo.php new file mode 100644 index 0000000..aff54fd --- /dev/null +++ b/fproject/amf/discovery/ClassFindInfo.php @@ -0,0 +1,55 @@ +absolutePath = $absolutePath; + $this->className = $className; + } + +} + +?> diff --git a/fproject/amf/discovery/MethodDescriptor.php b/fproject/amf/discovery/MethodDescriptor.php new file mode 100644 index 0000000..c0d45cd --- /dev/null +++ b/fproject/amf/discovery/MethodDescriptor.php @@ -0,0 +1,70 @@ +name = $name; + $this->parameters = $parameters; + $this->comment = $comment; + $this->returnType = $returnType; + } + +} + +?> diff --git a/fproject/amf/discovery/ParameterDescriptor.php b/fproject/amf/discovery/ParameterDescriptor.php new file mode 100644 index 0000000..2e8e258 --- /dev/null +++ b/fproject/amf/discovery/ParameterDescriptor.php @@ -0,0 +1,54 @@ +name = $name; + $this->type = $type; + } + +} + +?> diff --git a/fproject/amf/discovery/ServiceDescriptor.php b/fproject/amf/discovery/ServiceDescriptor.php new file mode 100644 index 0000000..9fe1db9 --- /dev/null +++ b/fproject/amf/discovery/ServiceDescriptor.php @@ -0,0 +1,59 @@ +name = $name; + $this->methods = $methods; + $this->comment = $comment; + } +} + +?> diff --git a/fproject/amf/discovery/ServiceRouter.php b/fproject/amf/discovery/ServiceRouter.php new file mode 100644 index 0000000..a51b7b5 --- /dev/null +++ b/fproject/amf/discovery/ServiceRouter.php @@ -0,0 +1,178 @@ +serviceFolderPaths = $serviceFolderPaths; + $this->serviceNames2ClassFindInfo = $serviceNames2ClassFindInfo; + $this->checkArgumentCount = $checkArgumentCount; + } + + /** + * get a service object by its name. Looks for a match in serviceNames2ClassFindInfo, then in the defined service folders. + * If none found, an exception is thrown + * @todo maybe option for a fully qualified class name. + * this method is static so that it can be used also by the discovery service + * '__' are replaced by '/' to help the client generator support packages without messing with folders and the like + * + * @param type $serviceName + * @param array $serviceFolderPaths + * @param array $serviceNames2ClassFindInfo + * @throws Zend_Exception + * @return Object service object + */ + public static function getServiceObjectStatically($serviceName, array $serviceFolderPaths, array $serviceNames2ClassFindInfo){ + $serviceObject = null; + if (isset($serviceNames2ClassFindInfo[$serviceName])) { + $classFindInfo = $serviceNames2ClassFindInfo[$serviceName]; + $s = $classFindInfo->absolutePath; + if(strcasecmp(substr($s, -4),'.php') !== 0) + { + $s = $s.'.php'; + } + require_once $s; + $serviceObject = new $classFindInfo->className(); + } else { + $temp = str_replace('.', '/', $serviceName); + $serviceNameWithSlashes = str_replace('__', '/', $temp); + $serviceIncludePath = $serviceNameWithSlashes . '.php'; + $exploded = explode('/', $serviceNameWithSlashes); + $className = $exploded[count($exploded) - 1]; + //no class find info. try to look in the folders + foreach ($serviceFolderPaths as $folderPath) { + if(substr($folderPath, -1) !== '/') + { + $folderPath = $folderPath.'/'; + } + $servicePath = $folderPath . $serviceIncludePath; + if (file_exists($servicePath)) { + require_once $servicePath; + $serviceObject = new $className(); + break; + } + } + } + + if (!$serviceObject) { + throw new Zend_Exception("Service not found: $serviceName"); + } + return $serviceObject; + + } + + /** + * get service object + * @param String $serviceName + * @return Object service object + */ + public function getServiceObject($serviceName) { + return self::getServiceObjectStatically($serviceName, $this->serviceFolderPaths, $this->serviceNames2ClassFindInfo); + } + + /** + * loads and instanciates a service class matching $serviceName, then calls the function defined by $methodName using $parameters as parameters + * throws an exception if service not found. + * if the service exists but not the function, an exception is thrown by call_user_func_array. It is pretty explicit, so no further code was added + * + * @param string $serviceName + * @param string $methodName + * @param array $parameters + * @return mixed the result of the function call + * + */ + public function executeServiceCall($serviceName, $methodName, array $parameters) { + $unfilteredServiceObject = $this->getServiceObject($serviceName); + $serviceObject = Amfphp_Core_FilterManager::getInstance()->callFilters(self::FILTER_SERVICE_OBJECT, $unfilteredServiceObject, $serviceName, $methodName, $parameters); + + $isStaticMethod = false; + + if(method_exists($serviceObject, $methodName)){ + //method exists, but isn't static + }else if (method_exists($serviceName, $methodName)) { + $isStaticMethod = true; + }else{ + throw new Amfphp_Core_Exception("method $methodName not found on $serviceName object "); + } + + if(substr($methodName, 0, 1) == '_'){ + throw new Exception("The method $methodName starts with a '_', and is therefore not accessible"); + } + + if($this->checkArgumentCount){ + $method = new ReflectionMethod($serviceObject, $methodName); + $numberOfRequiredParameters = $method->getNumberOfRequiredParameters(); + $numberOfParameters = $method->getNumberOfParameters(); + $numberOfProvidedParameters = count($parameters); + if ($numberOfProvidedParameters < $numberOfRequiredParameters || $numberOfProvidedParameters > $numberOfParameters) { + throw new Amfphp_Core_Exception("Invalid number of parameters for method $methodName in service $serviceName : $numberOfRequiredParameters required, $numberOfParameters total, $numberOfProvidedParameters provided"); + } + } + if($isStaticMethod){ + return call_user_func_array(array($serviceName, $methodName), $parameters); + }else{ + return call_user_func_array(array($serviceObject, $methodName), $parameters); + } + } + + +} + +?> \ No newline at end of file