/**
  * Adds properties of the class at hand to the class schema.
  *
  * Only non-transient properties annotated with a var annotation will be added.
  * Invalid annotations will cause an exception to be thrown. Properties pointing
  * to existing classes will only be added if the target type is annotated as
  * entity or valueobject.
  *
  * @param \TYPO3\Flow\Reflection\ClassSchema $classSchema
  * @return void
  * @throws \InvalidArgumentException
  * @throws \TYPO3\Flow\Reflection\Exception\InvalidPropertyTypeException
  */
 protected function addPropertiesToClassSchema(ClassSchema $classSchema)
 {
     // those are added as property even if not tagged with entity/valueobject
     $propertyTypeWhiteList = array('DateTime', 'SplObjectStorage', 'Doctrine\\Common\\Collections\\Collection', 'Doctrine\\Common\\Collections\\ArrayCollection');
     $className = $classSchema->getClassName();
     $needsArtificialIdentity = TRUE;
     foreach ($this->getClassPropertyNames($className) as $propertyName) {
         if ($this->isPropertyTaggedWith($className, $propertyName, 'var') && !$this->isPropertyAnnotatedWith($className, $propertyName, 'TYPO3\\Flow\\Annotations\\Transient')) {
             $varTagValues = $this->getPropertyTagValues($className, $propertyName, 'var');
             if (count($varTagValues) > 1) {
                 throw new InvalidPropertyTypeException('More than one @var annotation given for "' . $className . '::$' . $propertyName . '"', 1367334366);
             } else {
                 $declaredType = strtok(trim(current($varTagValues), " \n\t"), " \n\t");
             }
             if ($this->isPropertyAnnotatedWith($className, $propertyName, 'Doctrine\\ORM\\Mapping\\Id')) {
                 $needsArtificialIdentity = FALSE;
             }
             try {
                 $parsedType = TypeHandling::parseType($declaredType);
             } catch (InvalidTypeException $exception) {
                 throw new \InvalidArgumentException(sprintf($exception->getMessage(), 'class "' . $className . '" for property "' . $propertyName . '"'), 1315564475);
             }
             if (!in_array($parsedType['type'], $propertyTypeWhiteList) && (class_exists($parsedType['type']) || interface_exists($parsedType['type'])) && !($this->isClassAnnotatedWith($parsedType['type'], 'TYPO3\\Flow\\Annotations\\Entity') || $this->isClassAnnotatedWith($parsedType['type'], 'Doctrine\\ORM\\Mapping\\Entity') || $this->isClassAnnotatedWith($parsedType['type'], 'TYPO3\\Flow\\Annotations\\ValueObject'))) {
                 continue;
             }
             $classSchema->addProperty($propertyName, $declaredType, $this->isPropertyAnnotatedWith($className, $propertyName, 'TYPO3\\Flow\\Annotations\\Lazy'));
             if ($this->isPropertyAnnotatedWith($className, $propertyName, 'TYPO3\\Flow\\Annotations\\Identity')) {
                 $classSchema->markAsIdentityProperty($propertyName);
             }
         }
     }
     if ($needsArtificialIdentity === TRUE) {
         $classSchema->addProperty('Persistence_Object_Identifier', 'string');
     }
 }
 /**
  * @param ClassSchema $classSchema
  * @param string $propertyName
  * @return boolean
  * @throws InvalidPropertyTypeException
  * @throws \InvalidArgumentException
  */
 protected function evaluateClassPropertyAnnotationsForSchema(ClassSchema $classSchema, $propertyName)
 {
     $skipArtificialIdentity = false;
     $className = $classSchema->getClassName();
     if ($this->isPropertyAnnotatedWith($className, $propertyName, Flow\Transient::class)) {
         return false;
     }
     if ($this->isPropertyAnnotatedWith($className, $propertyName, Flow\Inject::class)) {
         return false;
     }
     if (!$this->isPropertyTaggedWith($className, $propertyName, 'var')) {
         return false;
     }
     $varTagValues = $this->getPropertyTagValues($className, $propertyName, 'var');
     if (count($varTagValues) > 1) {
         throw new InvalidPropertyTypeException('More than one @var annotation given for "' . $className . '::$' . $propertyName . '"', 1367334366);
     }
     $declaredType = strtok(trim(current($varTagValues), " \n\t"), " \n\t");
     try {
         TypeHandling::parseType($declaredType);
     } catch (InvalidTypeException $exception) {
         throw new \InvalidArgumentException(sprintf($exception->getMessage(), 'class "' . $className . '" for property "' . $propertyName . '"'), 1315564475);
     }
     if ($this->isPropertyAnnotatedWith($className, $propertyName, ORM\Id::class)) {
         $skipArtificialIdentity = true;
     }
     $classSchema->addProperty($propertyName, $declaredType, $this->isPropertyAnnotatedWith($className, $propertyName, Flow\Lazy::class), $this->isPropertyAnnotatedWith($className, $propertyName, Flow\Transient::class));
     if ($this->isPropertyAnnotatedWith($className, $propertyName, Flow\Identity::class)) {
         $classSchema->markAsIdentityProperty($propertyName);
     }
     return $skipArtificialIdentity;
 }
 /**
  * Adds properties of the class at hand to the class schema.
  *
  * Properties will be added if they have a var annotation && (!transient-annotation && !inject-annotation)
  *
  * Invalid annotations will cause an exception to be thrown.
  *
  * @param \TYPO3\Flow\Reflection\ClassSchema $classSchema
  * @return void
  * @throws Exception\InvalidPropertyTypeException
  */
 protected function addPropertiesToClassSchema(ClassSchema $classSchema)
 {
     $className = $classSchema->getClassName();
     $needsArtificialIdentity = true;
     foreach ($this->getClassPropertyNames($className) as $propertyName) {
         if ($this->isPropertyAnnotatedWith($className, $propertyName, \TYPO3\Flow\Annotations\Transient::class)) {
             continue;
         }
         if ($this->isPropertyAnnotatedWith($className, $propertyName, \TYPO3\Flow\Annotations\Inject::class)) {
             continue;
         }
         if ($this->isPropertyTaggedWith($className, $propertyName, 'var')) {
             $varTagValues = $this->getPropertyTagValues($className, $propertyName, 'var');
             if (count($varTagValues) > 1) {
                 throw new InvalidPropertyTypeException('More than one @var annotation given for "' . $className . '::$' . $propertyName . '"', 1367334366);
             } else {
                 $declaredType = strtok(trim(current($varTagValues), " \n\t"), " \n\t");
             }
             try {
                 TypeHandling::parseType($declaredType);
             } catch (InvalidTypeException $exception) {
                 throw new \InvalidArgumentException(sprintf($exception->getMessage(), 'class "' . $className . '" for property "' . $propertyName . '"'), 1315564475);
             }
             if ($this->isPropertyAnnotatedWith($className, $propertyName, 'Doctrine\\ORM\\Mapping\\Id')) {
                 $needsArtificialIdentity = false;
             }
             $classSchema->addProperty($propertyName, $declaredType, $this->isPropertyAnnotatedWith($className, $propertyName, \TYPO3\Flow\Annotations\Lazy::class), $this->isPropertyAnnotatedWith($className, $propertyName, \TYPO3\Flow\Annotations\Transient::class));
             if ($this->isPropertyAnnotatedWith($className, $propertyName, \TYPO3\Flow\Annotations\Identity::class)) {
                 $classSchema->markAsIdentityProperty($propertyName);
             }
         }
         if ($needsArtificialIdentity === true) {
             $classSchema->addProperty('Persistence_Object_Identifier', 'string');
         }
     }
 }