/**
* {@inheritDoc}
* @throws InvalidProxiedClassException
* @throws InvalidArgumentException
*/
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
{
CanProxyAssertion::assertClassCanBeProxied($originalClass, false);
$annotation = null;
$forceLazyInitProperty = new ForceLazyInitProperty();
$sessionBeansProperty = new SessionBeansProperty();
$postProcessorsProperty = new BeanPostProcessorsProperty();
$parameterValuesProperty = new ParameterValuesProperty();
$beanFactoryConfigurationProperty = new BeanFactoryConfigurationProperty();
$aliasesProperty = new AliasesProperty();
$getParameterMethod = new GetParameter($originalClass, $parameterValuesProperty);
$wrapBeanAsLazyMethod = new WrapBeanAsLazy($originalClass, $beanFactoryConfigurationProperty);
try {
$reader = new AnnotationReader();
$annotation = $reader->getClassAnnotation($originalClass, Configuration::class);
} catch (Exception $e) {
throw new InvalidProxiedClassException($e->getMessage(), $e->getCode(), $e);
}
if (null === $annotation) {
throw new InvalidProxiedClassException(sprintf('"%s" seems not to be a valid configuration class. @Configuration annotation missing!', $originalClass->getName()));
}
$classGenerator->setExtendedClass($originalClass->getName());
$classGenerator->setImplementedInterfaces([AliasContainerInterface::class]);
$classGenerator->addPropertyFromGenerator($forceLazyInitProperty);
$classGenerator->addPropertyFromGenerator($sessionBeansProperty);
$classGenerator->addPropertyFromGenerator($postProcessorsProperty);
$classGenerator->addPropertyFromGenerator($parameterValuesProperty);
$classGenerator->addPropertyFromGenerator($beanFactoryConfigurationProperty);
$classGenerator->addPropertyFromGenerator($aliasesProperty);
$postProcessorMethods = [];
$aliases = [];
$methods = $originalClass->getMethods(ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED);
foreach ($methods as $method) {
if (null !== $reader->getMethodAnnotation($method, BeanPostProcessor::class)) {
$postProcessorMethods[] = $method->getName();
continue;
}
/* @var \bitExpert\Disco\Annotations\Bean $beanAnnotation */
$beanAnnotation = $reader->getMethodAnnotation($method, Bean::class);
if (null === $beanAnnotation) {
throw new InvalidProxiedClassException(sprintf('Method "%s" on "%s" is missing the @Bean annotation!', $method->getName(), $originalClass->getName()));
}
// if alias is defined append it to the aliases list
if ($beanAnnotation->getAlias() !== '' && !isset($aliases[$beanAnnotation->getAlias()])) {
$aliases[$beanAnnotation->getAlias()] = $method->getName();
}
/* @var \bitExpert\Disco\Annotations\Parameters $parametersAnnotation */
$parametersAnnotation = $reader->getMethodAnnotation($method, Parameters::class);
if (null === $parametersAnnotation) {
$parametersAnnotation = new Parameters();
}
$beanType = $method->getReturnType();
if (null === $beanType) {
throw new InvalidProxiedClassException(sprintf('Method "%s" on "%s" is missing the return typehint!', $method->getName(), $originalClass->getName()));
}
$beanType = (string) $beanType;
if (!in_array($beanType, ['array', 'callable', 'bool', 'float', 'int', 'string']) && !class_exists($beanType) && !interface_exists($beanType)) {
throw new InvalidProxiedClassException(sprintf('Return type of method "%s" on "%s" cannot be found! Did you use the full qualified name?', $method->getName(), $originalClass->getName()));
}
$methodReflection = new MethodReflection($method->class, $method->getName());
$proxyMethod = BeanMethod::generateMethod($methodReflection, $beanAnnotation, $parametersAnnotation, $beanType, $forceLazyInitProperty, $sessionBeansProperty, $postProcessorsProperty, $beanFactoryConfigurationProperty, $getParameterMethod, $wrapBeanAsLazyMethod);
$classGenerator->addMethodFromGenerator($proxyMethod);
}
$aliasesProperty->setDefaultValue($aliases);
$classGenerator->addMethodFromGenerator(new Constructor($originalClass, $parameterValuesProperty, $sessionBeansProperty, $beanFactoryConfigurationProperty, $postProcessorsProperty, $postProcessorMethods));
$classGenerator->addMethodFromGenerator($wrapBeanAsLazyMethod);
$classGenerator->addMethodFromGenerator($getParameterMethod);
$classGenerator->addMethodFromGenerator(new MagicSleep($originalClass, $sessionBeansProperty));
$classGenerator->addMethodFromGenerator(new GetAlias($originalClass, $aliasesProperty));
$classGenerator->addMethodFromGenerator(new HasAlias($originalClass, $aliasesProperty));
}