Changeset 492
- Timestamp:
- 04/13/07 13:56:11 (2 years ago)
- Files:
-
- trunk/src/main/php/net/stubbles/reflection/annotations/stubAnnotationFactory.php (modified) (5 diffs)
- trunk/src/test/php/net/stubbles/rdbms/persistence/MockMultiplePrimaryKeyPersistable.php (modified) (3 diffs)
- trunk/src/test/php/net/stubbles/rdbms/persistence/MockSinglePrimaryKeyPersistable.php (modified) (5 diffs)
- trunk/src/test/php/net/stubbles/rdbms/persistence/finder/stubDatabaseFinderTestCase.php (modified) (2 diffs)
- trunk/src/test/php/net/stubbles/reflection/annotations/stubAnnotationFactoryBuildTestCase.php (modified) (10 diffs)
- trunk/src/test/php/net/stubbles/reflection/annotations/stubAnnotationFactoryTestCase.php (modified) (4 diffs)
- trunk/src/test/php/net/stubbles/xml/stubXMLSerializerTestCase.php (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/main/php/net/stubbles/reflection/annotations/stubAnnotationFactory.php
r432 r492 25 25 * @var array 26 26 */ 27 private static $prefixes = array('stub'); 27 private static $prefixes = array('stub'); 28 /** 29 * instance of the annotation parser 30 * 31 * @var stubAnnotationStateParser 32 */ 33 private static $parser = null; 34 /** 35 * list of annotation data 36 * 37 * @var array<string,array<string,array<string,array<string,string>>>> 38 */ 39 private static $annotations = array(); 28 40 29 41 /** … … 43 55 } 44 56 45 // Fast annotation check 46 $start = stripos($comment, '@' . $annotationName); 47 if (false === $start) { 48 return null; 57 $hash = md5($comment); 58 if (isset(self::$annotations[$hash]) == false) { 59 if (null == self::$parser) { 60 self::$parser = new stubAnnotationStateParser(); 61 } 62 63 self::$annotations[$hash] = self::$parser->parse($comment); 49 64 } 50 65 51 list($annotationClass,$data) = self::parseAnnotation($comment, $annotationName); 52 if (false === $data) { 53 throw new ReflectionException('Error evaluating annotation: ' . $annotationName . substr($comment, $start, $strlen)); 66 if (isset(self::$annotations[$hash][$annotationName]) == false) { 67 throw new ReflectionException('Can not find annotation ' . $annotationName); 54 68 } 55 56 $annotationClass = self::findAnnotationClass($annotationClass); 57 58 $annotation = new $annotationClass(); 69 70 $annotationClass = self::findAnnotationClass(self::$annotations[$hash][$annotationName]['type']); 71 $annotation = new $annotationClass(); 59 72 60 73 if (($annotation instanceof stubAnnotation) == false) { 61 74 throw new ReflectionException('The annotation: ' . $annotationName . ' is not an instance of net.stubbles.reflection.annotations.stubAnnotation.'); 62 75 } 63 $annotationType = self::findAnnotationClass($annotationName, true); 64 if (!is_a($annotation, $annotationType)) { 65 throw new ReflectionException('The annotation: ' . $annotationName . ' is not an instance of ' . $annotationType . '.'); 76 77 if (self::$annotations[$hash][$annotationName]['type'] != $annotationName) { 78 $annotationType = self::findAnnotationClass($annotationName, true); 79 if (is_a($annotation, $annotationType) == false) { 80 throw new ReflectionException('The annotation: ' . $annotationName . ' is not an instance of ' . $annotationType . '.'); 81 } 66 82 } 83 67 84 if (self::isApplicable($annotation, $target) == false) { 68 85 throw new ReflectionException('The annotation: ' . $annotationName . ' is not applicable for the given type.'); 69 86 } 70 71 $annotation = self::build($annotation, $data);87 88 self::build($annotation, self::$annotations[$hash][$annotationName]['params']); 72 89 $annotation->setAnnotationName($annotationName); 73 90 stubAnnotationCache::put($target, $targetName, $annotationName, $annotation); 74 91 return $annotation; 75 }76 77 /**78 * Helper method to parse an annotation79 *80 * @param string $comment81 * @param string $annotationName82 * @return array83 *84 * @todo Speed up parsing85 */86 private static function parseAnnotation($comment, $annotationName) {87 // remove start and end of the comment88 $comment = trim(str_replace(array('/**', '*/'), '', $comment));89 90 $parts = explode('@', $comment);91 $annoLength = strlen($annotationName);92 foreach ($parts as $annotation) {93 // quick compare94 if (strncmp($annotation, $annotationName, $annoLength) != 0) {95 continue;96 }97 $params = substr($annotation, $annoLength);98 99 // check, whether annotation needs casting100 if ($params{0} === '[') {101 $end = strpos($params, ']');102 if (false == $end) {103 throw new ReflectionException('Could not parse annotation');104 }105 106 $annotationClass = substr($params, 1, $end-1);107 $params = substr($params, $end+1);108 } else {109 $annotationClass = $annotationName;110 }111 112 // check for empty annotation113 $params = trim(str_replace('*', '', $params));114 if ('' === $params) {115 return array($annotationClass, array());116 }117 118 if ('(' === $params{0}) {119 $params = substr($params, 1, strlen($params) - 2);120 }121 122 $tmpParams = explode(',', $params);123 if (count($tmpParams) === 1 && false === strchr($tmpParams[0], '=')) {124 return array($annotationClass, array('value' => trim($tmpParams[0])));125 }126 127 $params = array();128 foreach ($tmpParams as $param) {129 $param = trim($param);130 if (false === strchr($param, '=')) {131 throw new ReflectionException('Unable to parse the annotation.');132 }133 134 $tmp = explode('=', $param);135 if (count($tmp) != 2) {136 throw new ReflectionException('Unable to parse the annotation.');137 }138 139 list($paramName,$paramValue) = $tmp;140 $params[trim($paramName)] = trim($paramValue);141 }142 143 return array($annotationClass, $params);144 }145 92 } 146 93 … … 162 109 * @param stubAnnotation $annotation the annotation to build 163 110 * @param array $data data for annotation 164 * @return stubAnnotation165 111 * @throws ReflectionException in case setting a data value fails 166 112 */ 167 113 public static function build(stubAnnotation $annotation, array $data) 168 114 { 169 $refClass = new ReflectionClass($annotation);115 $refClass = new ReflectionClass($annotation); 170 116 foreach ($data as $name => $value) { 171 117 if ($refClass->hasMethod('set' . ucfirst($name)) == true) { 172 $refMethod = $refClass->getMethod('set' . ucfirst($name)); 173 if ($refMethod->isPublic() == false || $refMethod->isStatic() == true) { 174 throw new ReflectionException('Annotation value for "' . $name . '" can not be set: setter with this name is static or not public.'); 175 } 176 $refMethod->invoke($annotation, $value); 118 $refClass->getMethod('set' . ucfirst($name))->invoke($annotation, $value); 177 119 } elseif ($refClass->hasProperty($name) == true) { 178 $refProperty = $refClass->getProperty($name); 179 if ($refProperty->isPublic() == false || $refProperty->isStatic() == true) { 180 throw new ReflectionException('Annotation value for "' . $name . '" can not be set: property with this name is static or not public.'); 181 } 182 $refProperty->setValue($annotation, $value); 120 $refClass->getProperty($name)->setValue($annotation, $value); 183 121 } else { 184 122 throw new ReflectionException('Annotation value for "' . $name . '" can not be set: no public setter and no public property exists with this name.'); 185 123 } 186 124 } 187 return $annotation;188 125 } 189 126 … … 209 146 * Add a new annotation prefix 210 147 * 211 * @param string$prefix148 * @param string $prefix 212 149 */ 213 public static function addAnnotationPrefix($prefix) { 150 public static function addAnnotationPrefix($prefix) 151 { 214 152 self::$prefixes[] = $prefix; 215 153 } … … 221 159 * or a method that has one of the prefixes defined in $prefixes and the postfix 'Annotation'. 222 160 * 223 * @param string$annotationClass224 * @return string225 * @see addAnnotationPrefix()161 * @param string $annotationClass 162 * @return string 163 * @see addAnnotationPrefix() 226 164 */ 227 private static function findAnnotationClass($annotationClass, $allowInterface = false) { 165 private static function findAnnotationClass($annotationClass, $allowInterface = false) 166 { 228 167 if (class_exists($annotationClass, false) == true) { 229 168 return $annotationClass; 230 169 } 231 if ($allowInterface && interface_exists($annotationClass, false)) { 170 171 if (true == $allowInterface && interface_exists($annotationClass, false) == true) { 232 172 return $annotationClass; 233 173 } 174 234 175 $annotationClassname = $annotationClass . 'Annotation'; 235 176 foreach (self::$prefixes as $prefix) { 236 if (class_exists($prefix . $annotationClassname) ) {177 if (class_exists($prefix . $annotationClassname) == true) { 237 178 return $prefix . $annotationClassname; 238 179 } 239 if ($allowInterface && interface_exists($prefix . $annotationClassname, false)) { 180 181 if (true == $allowInterface && interface_exists($prefix . $annotationClassname, false) == true) { 240 182 return $prefix . $annotationClassname; 241 183 } 242 184 } 185 243 186 throw new ReflectionException('Error parsing annotation: Class ' . $annotationClass . ' does not exist'); 244 187 } trunk/src/test/php/net/stubbles/rdbms/persistence/MockMultiplePrimaryKeyPersistable.php
r482 r492 12 12 * @package stubbles 13 13 * @subpackage rdbms_persistence_test 14 * @DBTable(name= foo)14 * @DBTable(name='foo') 15 15 */ 16 16 class MockMultiplePrimaryKeyPersistable extends stubAbstractPersistable … … 27 27 * 28 28 * @return string 29 * @DBColumn(name= id,type=INT,size=10,isUnsigned=true,isPrimaryKey=true)29 * @DBColumn(name='id', type='INT', size=10, isUnsigned=true, isPrimaryKey=true) 30 30 */ 31 31 public function getId() … … 47 47 * method that has a DBColumn annotation 48 48 * 49 * @DBColumn(name= id2,type=VARCHAR,size=10,isPrimaryKey=true)49 * @DBColumn(name='id2', type='VARCHAR', size=10, isPrimaryKey=true) 50 50 */ 51 51 public function getSecondPrimaryKey() trunk/src/test/php/net/stubbles/rdbms/persistence/MockSinglePrimaryKeyPersistable.php
r482 r492 12 12 * @package stubbles 13 13 * @subpackage rdbms_persistence_test 14 * @DBTable(name= foo)14 * @DBTable(name='foo') 15 15 */ 16 16 class MockSinglePrimaryKeyPersistable extends stubAbstractPersistable … … 33 33 * 34 34 * @return string 35 * @DBColumn(name= id,type=INT,size=10,isUnsigned=true,isPrimaryKey=true)35 * @DBColumn(name='id', type='INT', size=10, isUnsigned=true, isPrimaryKey=true) 36 36 */ 37 37 public function getId() … … 58 58 * method that has a DBColumn annotation 59 59 * 60 * @DBColumn(name= bar,type=VARCHAR,size=10,isNullable=true,setterMethod=setBar)60 * @DBColumn(name='bar', type='VARCHAR', size=10, isNullable=true, setterMethod='setBar') 61 61 */ 62 62 public function withAnnotation() … … 78 78 * method that has a DBColumn annotation 79 79 * 80 * @DBColumn(name= default,type=VARCHAR,size=10,defaultValue=example,setterMethod=setDefaultValue)80 * @DBColumn(name='default', type='VARCHAR', size=10, defaultValue='example', setterMethod='setDefaultValue') 81 81 */ 82 82 public function withDefaultValue() … … 87 87 /** 88 88 * method that has a DBColumn annotation but from another table 89 * , condition="`foo`.`id` = `blub`.`id`"89 * , condition="`foo`.`id` = `blub`.`id`" 90 90 * 91 * @DBColumn(name= baz,type=VARCHAR,size=10)92 * @DBJoin(name= blub,type=INNER,conditionType=ON)91 * @DBColumn(name='baz', type='VARCHAR', size=10) 92 * @DBJoin(name='blub', type='INNER', conditionType='ON') 93 93 */ 94 94 public function otherTable() trunk/src/test/php/net/stubbles/rdbms/persistence/finder/stubDatabaseFinderTestCase.php
r482 r492 17 17 * This is a class not implementing the persistable interface. 18 18 * 19 * @DBTable(name= bar)19 * @DBTable(name='bar') 20 20 */ 21 21 class TestNonPersistable { } … … 23 23 * This is a persistable that requires arguments in the constructor. 24 24 * 25 * @DBTable(name= bar)25 * @DBTable(name='bar') 26 26 */ 27 27 class MockInstanceArgsPersistable extends stubAbstractPersistable trunk/src/test/php/net/stubbles/reflection/annotations/stubAnnotationFactoryBuildTestCase.php
r432 r492 8 8 */ 9 9 stubClassLoader::load('net.stubbles.reflection.annotations.stubAnnotationFactory'); 10 Mock::generate('stubAnnotation');11 10 class stubMethodAnnotation implements stubAnnotation 12 11 { … … 26 25 27 26 private function setBar2($bar) {} 28 29 public static function setBaz($baz) {} 30 27 31 28 public function setAnnotationName($name) {} 32 29 public function getAnnotationName() {} … … 52 49 { 53 50 /** 54 * annotation to use for tests55 *56 * @var stubAnnotation57 */58 protected $mockStubAnnotation;59 60 /**61 * create test environment62 */63 public function setUp()64 {65 $this->mockStubAnnotation = new MockStubAnnotation();66 }67 68 /**69 * check that building the annotation works correct70 */71 public function testBuildWithEmptyData()72 {73 $mockStubAnnotation = new MockStubAnnotation();74 $data = array();75 $result = stubAnnotationFactory::build($mockStubAnnotation, $data);76 $this->assertReference($result, $mockStubAnnotation);77 }78 79 /**80 51 * check that building the annotation works correct 81 52 */ … … 83 54 { 84 55 $stubAnnotation = new stubMethodAnnotation(); 85 $data = array('foo' => 'bar'); 86 $result = stubAnnotationFactory::build($stubAnnotation, $data); 87 $this->assertReference($result, $stubAnnotation); 56 $data = array('foo' => 'bar'); 57 stubAnnotationFactory::build($stubAnnotation, $data); 88 58 $this->assertEqual($stubAnnotation->getFoo(), 'bar'); 89 59 } … … 95 65 { 96 66 $stubAnnotation = new stubMethodAnnotation(); 97 $data = array('bar' => 'baz');67 $data = array('bar' => 'baz'); 98 68 $this->expectException('ReflectionException'); 99 $result =stubAnnotationFactory::build($stubAnnotation, $data);69 stubAnnotationFactory::build($stubAnnotation, $data); 100 70 } 101 71 … … 106 76 { 107 77 $stubAnnotation = new stubMethodAnnotation(); 108 $data = array('bar2' => 'baz2');78 $data = array('bar2' => 'baz2'); 109 79 $this->expectException('ReflectionException'); 110 $result =stubAnnotationFactory::build($stubAnnotation, $data);80 stubAnnotationFactory::build($stubAnnotation, $data); 111 81 } 112 113 /** 114 * check that building the annotation works correct 115 */ 116 public function testBuildWithStaticMethod() 117 { 118 $stubAnnotation = new stubMethodAnnotation(); 119 $data = array('baz' => 'foo'); 120 $this->expectException('ReflectionException'); 121 $result = stubAnnotationFactory::build($stubAnnotation, $data); 122 } 123 82 124 83 /** 125 84 * check that building the annotation works correct … … 128 87 { 129 88 $stubAnnotation = new stubPropertyAnnotation(); 130 $data = array('foo' => 'bar'); 131 $result = stubAnnotationFactory::build($stubAnnotation, $data); 132 $this->assertReference($result, $stubAnnotation); 89 $data = array('foo' => 'bar'); 90 stubAnnotationFactory::build($stubAnnotation, $data); 133 91 $this->assertEqual($stubAnnotation->foo, 'bar'); 134 92 } … … 140 98 { 141 99 $stubAnnotation = new stubPropertyAnnotation(); 142 $data = array('bar' => 'baz');100 $data = array('bar' => 'baz'); 143 101 $this->expectException('ReflectionException'); 144 $result =stubAnnotationFactory::build($stubAnnotation, $data);102 stubAnnotationFactory::build($stubAnnotation, $data); 145 103 } 146 104 … … 151 109 { 152 110 $stubAnnotation = new stubPropertyAnnotation(); 153 $data = array('bar2' => 'baz2');111 $data = array('bar2' => 'baz2'); 154 112 $this->expectException('ReflectionException'); 155 $result =stubAnnotationFactory::build($stubAnnotation, $data);113 stubAnnotationFactory::build($stubAnnotation, $data); 156 114 } 157 158 /** 159 * check that building the annotation works correct 160 */ 161 public function testBuildWithStaticProperty() 162 { 163 $stubAnnotation = new stubPropertyAnnotation(); 164 $data = array('baz' => 'foo'); 165 $this->expectException('ReflectionException'); 166 $result = stubAnnotationFactory::build($stubAnnotation, $data); 167 } 168 115 169 116 /** 170 117 * check that building the annotation works correct … … 173 120 { 174 121 $stubAnnotation = new stubPropertyAnnotation(); 175 $data = array('example' => 'foo');122 $data = array('example' => 'foo'); 176 123 $this->expectException('ReflectionException'); 177 $result =stubAnnotationFactory::build($stubAnnotation, $data);124 stubAnnotationFactory::build($stubAnnotation, $data); 178 125 } 179 126 } trunk/src/test/php/net/stubbles/reflection/annotations/stubAnnotationFactoryTestCase.php
r432 r492 69 69 * 70 70 * @MyAnnotation( 71 * foo= bar,71 * foo='bar', 72 72 * argh=true, 73 * veggie= cucumber73 * veggie='cucumber' 74 74 * ) 75 75 */ … … 91 91 * @var string 92 92 */ 93 protected $comment = "/**\n * a test docblock\n * \n * \n * @param string \$foo\n * @StubAnnotation(foo = blub);\n */";93 protected $comment = "/**\n * a test docblock\n * \n * \n * @param string \$foo\n * @StubAnnotation(foo = 'blub');\n */"; 94 94 95 95 protected $commentComplex = '/** … … 98 98 * @access public 99 99 * @MyAnnotation( 100 * foo= bar,101 * argh=45, veggie= tomato100 * foo="bar", 101 * argh=45, veggie="tomato" 102 102 * ) 103 103 * @AnotherAnnotation(true) … … 141 141 $castedAnnotation = stubAnnotationFactory::create($this->commentComplex, 'CastedAnnotation', stubAnnotation::TARGET_CLASS, 'MyClass'); 142 142 $this->assertIsA($castedAnnotation, 'AnotherAnnotation'); 143 $this->assert Equal('false',$castedAnnotation->value);143 $this->assertFalse($castedAnnotation->value); 144 144 145 $ nonExistingAnnotation = stubAnnotationFactory::create($this->commentComplex, 'NonExisting', stubAnnotation::TARGET_CLASS, 'MyClass');146 $this->assertNull($nonExistingAnnotation);145 $this->expectException('ReflectionException'); 146 stubAnnotationFactory::create($this->commentComplex, 'NonExisting', stubAnnotation::TARGET_CLASS, 'MyClass'); 147 147 } 148 148 trunk/src/test/php/net/stubbles/xml/stubXMLSerializerTestCase.php
r393 r492 29 29 * Simple Test class to test the XMLSerializer 30 30 * 31 * @XMLTag(tagName= foo)31 * @XMLTag(tagName='foo') 32 32 */ 33 33 class XMLSerializerFoo { … … 37 37 * 38 38 * @var int 39 * @XMLTag(tagName= bar)39 * @XMLTag(tagName='bar') 40 40 */ 41 41 public $bar = 42; … … 45 45 * 46 46 * @var string 47 * @XMLAttribute(attributeName= bar)47 * @XMLAttribute(attributeName='bar') 48 48 */ 49 49 public $scalar = "test"; … … 61 61 * Simple Test class to test the XMLSerializer 62 62 * 63 * @XMLTag(tagName= container)63 * @XMLTag(tagName='container') 64 64 */ 65 65 class XMLSerializerList { … … 69 69 * 70 70 * @var int 71 * @XMLTag(tagName= list,elementTagName=item)71 * @XMLTag(tagName='list', elementTagName='item') 72 72 */ 73 73 public $bar = array('one', 'two', 'three'); … … 77 77 * Simple Test class to test the XMLSerializer 78 78 * 79 * @XMLTag(tagName= class)79 * @XMLTag(tagName='class') 80 80 */ 81 81 class XMLSerializerMethods { … … 89 89 * 90 90 * @return string 91 * @XMLAttribute(attributeName= method)91 * @XMLAttribute(attributeName='method') 92 92 */ 93 93 public function getValue() { … … 99 99 * Simple Test class to test the XMLSerializer 100 100 * 101 * @XMLTag(tagName= testObject)102 * @XMLProperties[XMLMatcher](pattern= /^([a-zA-Z]{3})$/)101 * @XMLTag(tagName='testObject') 102 * @XMLProperties[XMLMatcher](pattern='/^([a-zA-Z]{3})$/') 103 103 */ 104 104 class XMLSerializerPropertyMatcher { … … 112 112 * Simple Test class to test the XMLSerializer 113 113 * 114 * @XMLTag(tagName= testObject)115 * @XMLMethods[XMLMatcher](pattern= /^get(F.+)/)114 * @XMLTag(tagName='testObject') 115 * @XMLMethods[XMLMatcher](pattern='/^get(F.+)/') 116 116 */ 117 117 class XMLSerializerMethodMatcher {
