| 9 | | stubClassLoader::load('net::stubbles::xml::serializer::annotations::stubXMLTagAnnotation', |
|---|
| 10 | | 'net::stubbles::xml::serializer::annotations::stubXMLFragmentAnnotation', |
|---|
| 11 | | 'net::stubbles::xml::serializer::annotations::stubXMLAttributeAnnotation', |
|---|
| 12 | | 'net::stubbles::xml::serializer::annotations::stubXMLIgnoreAnnotation', |
|---|
| 13 | | 'net::stubbles::xml::serializer::annotations::stubXMLPropertiesAnnotation', |
|---|
| 14 | | 'net::stubbles::xml::serializer::annotations::stubXMLMethodsAnnotation', |
|---|
| 15 | | 'net::stubbles::xml::serializer::annotations::stubXMLMatcherAnnotation', |
|---|
| 16 | | 'net::stubbles::xml::serializer::annotations::stubXMLStrategyAnnotation', |
|---|
| 17 | | 'net::stubbles::xml::serializer::matcher::stubXMLSerializerMethodPropertyMatcher', |
|---|
| 18 | | 'net::stubbles::reflection::reflection' |
|---|
| | 10 | stubClassLoader::load('net::stubbles::xml::stubXMLStreamWriter', |
|---|
| | 11 | 'net::stubbles::xml::serializer::stubXMLSerializerObjectData' |
|---|
| 166 | | $clazz = new stubReflectionClass(get_class($object)); |
|---|
| | 139 | $serializerData = stubXMLSerializerObjectData::fromObject($object); |
|---|
| | 140 | $xmlWriter->writeStartElement($serializerData->getTagName($tagName)); |
|---|
| | 141 | $strategy = $serializerData->getStrategy($this->opts[self::OPT_STRATEGY]); |
|---|
| | 142 | foreach ($serializerData->getProperties() as $propertyName => $propertyData) { |
|---|
| | 143 | $this->handle($object->$propertyName, $xmlWriter, $propertyData, ($strategy & self::STRATEGY_PROPS)); |
|---|
| | 144 | } |
|---|
| | 145 | |
|---|
| | 146 | foreach ($serializerData->getMethods() as $methodName => $methodData) { |
|---|
| | 147 | $this->handle($object->$methodName(), $xmlWriter, $methodData, ($strategy & self::STRATEGY_METHODS)); |
|---|
| | 148 | } |
|---|
| | 149 | |
|---|
| | 150 | $xmlWriter->writeEndElement(); |
|---|
| | 151 | } |
|---|
| | 152 | |
|---|
| | 153 | /** |
|---|
| | 154 | * serializes given value with instructions from $data |
|---|
| | 155 | * |
|---|
| | 156 | * @param mixed $value the value to serialize |
|---|
| | 157 | * @param stubXMLStreamWriter $xmlWriter XML Writer to use |
|---|
| | 158 | * @param array<string,array<string,scalar>> $data instructions on how to serialize |
|---|
| | 159 | * @param int $mustSerialize whether the element must be serialized or not |
|---|
| | 160 | */ |
|---|
| | 161 | protected function handle($value, stubXMLStreamWriter $xmlWriter, array $data, $mustSerialize) |
|---|
| | 162 | { |
|---|
| | 163 | switch ($data['type']) { |
|---|
| | 164 | case 'attribute': |
|---|
| | 165 | if ('' === (string) $value && true === $data['shouldSkipEmpty']) { |
|---|
| | 166 | return; |
|---|
| | 167 | } |
|---|
| | 168 | |
|---|
| | 169 | $xmlWriter->writeAttribute($data['attributeName'], (string) $value); |
|---|
| | 170 | break; |
|---|
| | 171 | |
|---|
| | 172 | case 'fragment': |
|---|
| | 173 | if (null != $data['tagName']) { |
|---|
| | 174 | $xmlWriter->writeStartElement($data['tagName']); |
|---|
| | 175 | $xmlWriter->writeXmlFragment($value); |
|---|
| | 176 | $xmlWriter->writeEndElement(); |
|---|
| | 177 | } else { |
|---|
| | 178 | $xmlWriter->writeXmlFragment($value); |
|---|
| | 179 | } |
|---|
| | 180 | break; |
|---|
| | 181 | |
|---|
| | 182 | default: |
|---|
| | 183 | if (false === $data['mustSerialize'] && 0 === $mustSerialize) { |
|---|
| | 184 | return; |
|---|
| | 185 | } |
|---|
| | 186 | |
|---|
| | 187 | if (is_array($value) === true) { |
|---|
| | 188 | $this->serializeArray($value, $xmlWriter, $data['tagName'], $data['elementName']); |
|---|
| | 189 | } else { |
|---|
| | 190 | $this->serializeDispatcher($value, $xmlWriter, $data['tagName']); |
|---|
| | 191 | } |
|---|
| | 192 | } |
|---|
| | 193 | } |
|---|
| | 194 | |
|---|
| | 195 | /** |
|---|
| | 196 | * serialize an array |
|---|
| | 197 | * |
|---|
| | 198 | * @param array $array array to serialize |
|---|
| | 199 | * @param stubXMLStreamWriter $xmlWriter XML Writer to use |
|---|
| | 200 | * @param string $tagName 'root' name for the array |
|---|
| | 201 | * @param string $defaultTag The default tag for indexed arrays |
|---|
| | 202 | */ |
|---|
| | 203 | protected function serializeArray($array, stubXMLStreamWriter $xmlWriter, $tagName, $defaultTag = null) |
|---|
| | 204 | { |
|---|
| 168 | | if ($clazz->hasAnnotation('XMLTag') === true) { |
|---|
| 169 | | $tagName = $clazz->getAnnotation('XMLTag')->getTagName(); |
|---|
| 170 | | } else { |
|---|
| 171 | | $tagName = get_class($object); |
|---|
| 172 | | } |
|---|
| 173 | | } |
|---|
| 174 | | |
|---|
| 175 | | $xmlWriter->writeStartElement($tagName); |
|---|
| 176 | | if ($clazz->hasAnnotation('XMLStrategy')) { |
|---|
| 177 | | $strategy = $clazz->getAnnotation('XMLStrategy')->getValue(); |
|---|
| 178 | | } else { |
|---|
| 179 | | $strategy = $this->opts[self::OPT_STRATEGY]; |
|---|
| 180 | | } |
|---|
| 181 | | |
|---|
| 182 | | // export props |
|---|
| 183 | | $properties = $clazz->getPropertiesByMatcher($this->methodAndPropertyMatcher); |
|---|
| 184 | | $matcher = null; |
|---|
| 185 | | // get the property-matcher |
|---|
| 186 | | if ($clazz->hasAnnotation('XMLProperties')) { |
|---|
| 187 | | $matcher = $clazz->getAnnotation('XMLProperties'); |
|---|
| 188 | | } |
|---|
| 189 | | |
|---|
| 190 | | foreach ($properties as $property) { |
|---|
| 191 | | $propValue = $property->getValue($object); |
|---|
| 192 | | if ($this->writeAnnotatedElement($property, $xmlWriter, $propValue) === true) { |
|---|
| 193 | | continue; |
|---|
| 194 | | } |
|---|
| 195 | | |
|---|
| 196 | | if ($property->hasAnnotation('XMLTag') === true) { |
|---|
| 197 | | $xmlTag = $property->getAnnotation('XMLTag'); |
|---|
| 198 | | $tagName = $xmlTag->getTagName(); |
|---|
| 199 | | $elementName = $xmlTag->getElementTagName(); |
|---|
| 200 | | } else { |
|---|
| 201 | | if (null !== $matcher) { |
|---|
| 202 | | $tagName = $matcher->getTagnameForProperty($property, $propValue); |
|---|
| 203 | | if (false === $tagName) { |
|---|
| 204 | | continue; |
|---|
| 205 | | } |
|---|
| 206 | | } else { |
|---|
| 207 | | if (($strategy & self::STRATEGY_PROPS) === 0) { |
|---|
| 208 | | continue; |
|---|
| 209 | | } |
|---|
| 210 | | |
|---|
| 211 | | if ($this->opts[self::OPT_STATIC] === false && $property->isStatic() === true) { |
|---|
| 212 | | continue; |
|---|
| 213 | | } |
|---|
| 214 | | |
|---|
| 215 | | $tagName = $property->getName(); |
|---|
| 216 | | } |
|---|
| 217 | | $elementName = null; |
|---|
| 218 | | } |
|---|
| 219 | | |
|---|
| 220 | | if (is_array($propValue) === true) { |
|---|
| 221 | | $this->serializeArray($propValue, $xmlWriter, $tagName, $elementName); |
|---|
| 222 | | } else { |
|---|
| 223 | | $this->serializeDispatcher($propValue, $xmlWriter, $tagName); |
|---|
| 224 | | } |
|---|
| 225 | | } |
|---|
| 226 | | |
|---|
| 227 | | // export methods |
|---|
| 228 | | $methods = $clazz->getMethodsByMatcher($this->methodAndPropertyMatcher); |
|---|
| 229 | | $matcher = null; |
|---|
| 230 | | // get the method-matcher |
|---|
| 231 | | if ($clazz->hasAnnotation('XMLMethods')) { |
|---|
| 232 | | $matcher = $clazz->getAnnotation('XMLMethods'); |
|---|
| 233 | | } |
|---|
| 234 | | |
|---|
| 235 | | foreach ($methods as $method) { |
|---|
| 236 | | $returnValue = $method->invoke($object); |
|---|
| 237 | | if ($this->writeAnnotatedElement($method, $xmlWriter, $returnValue) === true) { |
|---|
| 238 | | continue; |
|---|
| 239 | | } |
|---|
| 240 | | |
|---|
| 241 | | if ($method->hasAnnotation('XMLTag') === true) { |
|---|
| 242 | | $xmlTag = $method->getAnnotation('XMLTag'); |
|---|
| 243 | | $tagName = $xmlTag->getTagName(); |
|---|
| 244 | | $elementName = $xmlTag->getElementTagName(); |
|---|
| 245 | | } else { |
|---|
| 246 | | if (null !== $matcher) { |
|---|
| 247 | | $tagName = $matcher->getTagnameForMethod($method, $returnValue); |
|---|
| 248 | | if (false === $tagName) { |
|---|
| 249 | | continue; |
|---|
| 250 | | } |
|---|
| 251 | | } else { |
|---|
| 252 | | if (($strategy & self::STRATEGY_METHODS) === 0) { |
|---|
| 253 | | continue; |
|---|
| 254 | | } |
|---|
| 255 | | |
|---|
| 256 | | if ($this->opts[self::OPT_STATIC] === false && $method->isStatic() === true) { |
|---|
| 257 | | continue; |
|---|
| 258 | | } |
|---|
| 259 | | |
|---|
| 260 | | $tagName = $method->getName(); |
|---|
| 261 | | } |
|---|
| 262 | | |
|---|
| 263 | | $elementName = null; |
|---|
| 264 | | } |
|---|
| 265 | | |
|---|
| 266 | | if (is_array($returnValue) === true) { |
|---|
| 267 | | $this->serializeArray($returnValue, $xmlWriter, $tagName, $elementName); |
|---|
| 268 | | } else { |
|---|
| 269 | | $this->serializeDispatcher($returnValue, $xmlWriter, $tagName); |
|---|
| 270 | | } |
|---|
| 271 | | } |
|---|
| 272 | | |
|---|
| 273 | | $xmlWriter->writeEndElement(); |
|---|
| 274 | | } |
|---|
| 275 | | |
|---|
| 276 | | /** |
|---|
| 277 | | * serializes annotated element |
|---|
| 278 | | * |
|---|
| 279 | | * Returns true if element was serialized, else false. |
|---|
| 280 | | * |
|---|
| 281 | | * @param stubAnnotatable $annotatable the annotatable element to serialize |
|---|
| 282 | | * @param stubXMLStreamWriter $xmlWriter the xml writer to use |
|---|
| 283 | | * @param mixed $value the value to serialize |
|---|
| 284 | | * @return bool |
|---|
| 285 | | */ |
|---|
| 286 | | protected function writeAnnotatedElement(stubAnnotatable $annotatable, stubXMLStreamWriter $xmlWriter, $value) |
|---|
| 287 | | { |
|---|
| 288 | | if ($annotatable->hasAnnotation('XMLAttribute') === true) { |
|---|
| 289 | | $xmlAttribute = $annotatable->getAnnotation('XMLAttribute'); |
|---|
| 290 | | if ('' === (string) $value && $xmlAttribute->shouldSkipEmpty() === true) { |
|---|
| 291 | | return true; |
|---|
| 292 | | } |
|---|
| 293 | | |
|---|
| 294 | | $xmlWriter->writeAttribute($xmlAttribute->getAttributeName(), (string) $value); |
|---|
| 295 | | return true; |
|---|
| 296 | | } elseif ($annotatable->hasAnnotation('XMLFragment') === true) { |
|---|
| 297 | | $tagName = $annotatable->getAnnotation('XMLFragment')->getTagName(); |
|---|
| 298 | | if (null != $tagName) { |
|---|
| 299 | | $xmlWriter->writeStartElement($tagName); |
|---|
| 300 | | $xmlWriter->writeXmlFragment($value); |
|---|
| 301 | | $xmlWriter->writeEndElement(); |
|---|
| 302 | | } else { |
|---|
| 303 | | $xmlWriter->writeXmlFragment($value); |
|---|
| 304 | | } |
|---|
| 305 | | |
|---|
| 306 | | return true; |
|---|
| 307 | | } |
|---|
| 308 | | |
|---|
| 309 | | return false; |
|---|
| 310 | | } |
|---|
| 311 | | |
|---|
| 312 | | /** |
|---|
| 313 | | * Serialize an array |
|---|
| 314 | | * |
|---|
| 315 | | * @param array $array |
|---|
| 316 | | * @param stubXMLStreamWriter $xmlWriter |
|---|
| 317 | | * @param string $tagName The 'root' name for the array |
|---|
| 318 | | * @param string $defaultTag The default tag for indexed arrays |
|---|
| 319 | | */ |
|---|
| 320 | | protected function serializeArray($array, stubXMLStreamWriter $xmlWriter, $tagName, $defaultTag = null) |
|---|
| 321 | | { |
|---|
| 322 | | if ($tagName === null) { |
|---|