/** * Included by a client script? * * @param string $calling_component_filename Filename * * @return bool */ private static function _includedByAClientScriptThatIsNotAComponent($calling_component_filename) { $class_name = SCA_Helper::guessClassName($calling_component_filename); if (!class_exists($class_name, false)) { return true; } if (class_exists($class_name, false)) { $reflection = new ReflectionClass($class_name); $reader = new SCA_CommentReader($reflection->getDocComment()); if (!$reader->isService()) { return true; } } return false; }
/** * Invoke * * @return string */ public function invoke() { SCA::$logger->log('Entering'); //component_name, string reference_name, string method_name, array arguments // Reflection::export(new ReflectionObject($this->mediator)); try { // get the arguments from the mediator $arg_array = $this->mediator->getArgArray(); if ($this->class_name != null) { SCA::$logger->log('Attempt to create a service'); $this->service = new $this->class_name(); $reflection = new ReflectionObject($this->service); $reader = new SCA_CommentReader($reflection->getDocComment()); // if it's an SCA service recreate the instance // with all the references filled in if ($reader->isService()) { SCA::$logger->log('Create SCA service'); $this->service = SCA::createInstanceAndFillInReferences($this->class_name); } else { SCA::$logger->log('Create PHP object'); } } //invoke the function if ($this->service != null) { SCA::$logger->log('Invoke service as PHP object'); // it's a class with a member function // so call it. Even if it's an SCA service // we are not relying of SCA service bindings // at this point. We just want the references // that will have been set up on initialization // above. $return = call_user_func_array(array($this->service, $this->method_name), $arg_array); } else { if (function_exists($this->method_name)) { SCA::$logger->log('Invoke service as PHP function'); // it's not just a script so turn // off output buffering and then call // the function ob_end_clean(); $return = call_user_func_array($this->method_name, $arg_array); } else { SCA::$logger->log('Invoke service as PHP script'); // the script will have already executed // because it was included so all we have to // do here is return the contents of the // output buffer. $return = ob_get_contents(); ob_end_clean(); } } } catch (Exception $e) { SCA::$logger->log('Caught ' . $e->getMessage()); throw $e; } SCA::$logger->log('Exiting'); return $return; }
/** * Reflect service * * @return object SCA_ServiceDescription * @throws SCA_RuntimeException */ public function reflectService() { $reflection = $this->_getReflection(); $reader = new SCA_CommentReader($reflection->getDocComment()); $sca_name = $this->_getClassName(); /** * Check that this object is defining a service that will be * exposed to callers * [TODO] - this check needs converting to if (!local service) */ if (!$reader->isService()) { throw new SCA_RuntimeException("Class {$sca_name} does not contain an @service annotation."); } $service = new SCA_ServiceDescription(); $interface_reflection = null; if ($reader->isService()) { $service->interface_name = $reader->getServiceInterface(); // Get the ReflectionObject for any service interface $interface_reflection = $this->_getInterfaceReflection($reflection, $service->interface_name); if (is_null($interface_reflection)) { $interface_methods = null; if (!empty($service->interface_name)) { throw new SCA_RuntimeException("Service interface " . $service->interface_name . " specified by @service does not match any interface" . " implemented by {$sca_name}.php'."); } } else { $interface_methods = $interface_reflection->getMethods(); } $service->binding = $reader->getBindings(); } if (count($service->binding) == 0) { throw new SCA_RuntimeException("No valid @binding annotation could be found for '{$sca_name}.php'."); } $service->xsd_types = $this->reflectXsdTypes(); /* Filter reflected method array to show 'public' functions only */ $service_methods = SCA_Helper::filterMethods($this->_getMethods(), $reflection->getMethods(), $interface_methods); $operations = array(); $comment = null; /* Check the comment of each method to find any annotations so that * a wsdl can be generated from the .php file. */ foreach ($service_methods as $service_method) { $methodAnnotations = SCA_AnnotationRules::createEmptyAnnotationArray(); $comment = $service_method->getDocComment(); /* When the method has a doc comment .... */ if ($comment) { $method_reader = new SCA_CommentReader($comment); /* ... and the method a web service method .... */ if (!$method_reader->isWebMethod()) { continue; } /* ... decode any method annotations. */ $methodAnnotations = $method_reader->getMethodAnnotations(); if ($methodAnnotations == null) { continue; } $thisElement = 0; /* Each set of method annotations contain a set of 1 * or more parameter annotations, and 1 return * annotation. */ foreach ($methodAnnotations as $annotationSet) { // check that $annotationSet is not null to // take account of the situation where no // @return or @param annotation is specified if (!$annotationSet) { continue; } /* Clean off the dollar sign from the variable name, and do */ /* a namespace check as appropriate. */ foreach ($annotationSet as $annotation) { $is_param = strcmp($annotation['annotationType'], SCA_AnnotationRules::PARAM); if ($is_param === 0) { $has_dollar = strpos($annotation['name'], SCA_AnnotationRules::DOLLAR); if ($has_dollar === false) { throw new SCA_RuntimeException("Invalid syntax '" . $annotation['name'] . "' is not a php variable name"); } $methodAnnotations['parameters'][$thisElement]['name'] = trim($annotation['name'], SCA_AnnotationRules::DOLLAR); } /* When the array is formatted for SDO objects */ if (array_key_exists('namespace', $annotation)) { // check that the xsd is defined for the namespace $matched_xsds = $this->_matchXsds($service->xsd_types, $annotation['namespace']); if (!$matched_xsds) { /* TODO: noticed potential defect that if a method A has no @param, the @param of another method is being picked up instead and this error being thrown for method A */ throw new SCA_RuntimeException("Namespace defined in " . $annotation['annotationType'] . "not found in @types annotation: '" . $annotation['namespace'] . "'"); } } $thisElement++; // next annotation } } } /* Save the annotation set indexed by the method name. */ $operations[$service_method->getName()] = $methodAnnotations; } $service->operations = $operations; $service->binding_config = $reader->getNameValuePairs(); return $service; }