Skip to content

Commit

Permalink
Use the new naming logic for specifying the xml type name as well so …
Browse files Browse the repository at this point in the history
…that the encoder doesnt get confused
  • Loading branch information
veewee committed Jan 2, 2025
1 parent 77a2550 commit b25d608
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@

namespace Soap\WsdlReader\Metadata\Converter\Types\Configurator;

use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeItem;
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementItem;
use GoetasWebservices\XML\XSDReader\Schema\Item;
use GoetasWebservices\XML\XSDReader\Schema\SchemaItem;
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
use Soap\Engine\Metadata\Model\XsdType as EngineType;
use Soap\WsdlReader\Metadata\Converter\Types\Detector\AttributeTypeNameDetector;
use Soap\WsdlReader\Metadata\Converter\Types\Detector\ElementTypeNameDetector;
use Soap\WsdlReader\Metadata\Converter\Types\TypesConverterContext;

final class XmlTypeInfoConfigurator
Expand All @@ -25,9 +29,16 @@ public function __invoke(EngineType $engineType, mixed $xsdType, TypesConverterC
$targetNamespace = $xsdType->getSchema()->getTargetNamespace() ?? '';
$typeNamespace = $type?->getSchema()->getTargetNamespace() ?: $targetNamespace;

$parentContext = $context->parent()->unwrapOr(null);
$xmlTypeName = match(true) {
$parentContext && $item instanceof ElementItem => (new ElementTypeNameDetector())($item, $parentContext),
$parentContext && $item instanceof AttributeItem => (new AttributeTypeNameDetector())($item, $parentContext),
default => $typeName,
};

return $engineType
->withXmlTargetNodeName($itemName ?: $typeName)
->withXmlTypeName($typeName ?: $itemName ?: '')
->withXmlTypeName($xmlTypeName)
->withXmlNamespace($typeNamespace)
->withXmlNamespaceName(
$context->knownNamespaces->lookupNameFromNamespace($typeNamespace)->unwrapOr(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use GoetasWebservices\XML\XSDReader\Schema\SchemaItem;
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
use Psl\Option\Option;
use Soap\WsdlReader\Metadata\Converter\Types\ParentContext;
use function Psl\Option\none;
use function Psl\Option\some;

Expand Down Expand Up @@ -50,18 +49,4 @@ public function __invoke(AttributeItem $item, ?SchemaItem $parent): Option

return none();
}


/**
* @param Option<ParentContext> $parentContext
* @return Option<Type>
*/
public static function detectWithParentContext(AttributeItem $item, Option $parentContext): Option
{
/** @var self $calculate */
static $calculate = new self();

return $parentContext
->andThen(static fn (ParentContext $context) => $calculate($item, $context->currentParent()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);

namespace Soap\WsdlReader\Metadata\Converter\Types\Detector;

use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeItem;
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeSingle;
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
use Psl\Option\Option;
use Soap\WsdlReader\Metadata\Converter\Types\ParentContext;
use function Psl\Option\from_nullable;

final class AttributeTypeNameDetector
{
public function __invoke(AttributeItem $attribute, ParentContext $parentContext): string
{
$attributeType = $attribute instanceof AttributeSingle ? $attribute->getType() : null;
$attributeRestriction = $attributeType?->getRestriction();
$attributeTypeName = $attributeType?->getName();
$attributeRestrictionName = ($attributeRestriction && !$attributeRestriction->getChecks()) ? $attributeRestriction->getBase()?->getName() : null;

$typeName = $attributeTypeName ?: ($attributeRestrictionName ?: $attribute->getName());

// If a name cannot be determined from the type, we fallback to the attribute name:
// Prefix the attribute name with the parent element name resulting in a more unique type-name.
if (!$attributeTypeName && !$attributeRestrictionName) {
$typeName = (new AttributeDeclaringParentTypeDetector())($attribute, $parentContext->currentParent())
->andThen(static fn (Type $parent): Option => from_nullable($parent->getName()))
->map(static fn (string $parentName): string => $parentName . ucfirst($typeName))
->unwrapOr($typeName);
}

return $typeName;
}
}
29 changes: 3 additions & 26 deletions src/Metadata/Converter/Types/Visitor/AttributeContainerVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@

use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeContainer;
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeItem;
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeSingle;
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Group;
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
use Psl\Option\Option;
use Soap\Engine\Metadata\Collection\PropertyCollection;
use Soap\Engine\Metadata\Model\Property;
use Soap\Engine\Metadata\Model\TypeMeta;
use Soap\Engine\Metadata\Model\XsdType as EngineType;
use Soap\WsdlReader\Metadata\Converter\Types\Configurator;
use Soap\WsdlReader\Metadata\Converter\Types\Detector\AttributeDeclaringParentTypeDetector;
use Soap\WsdlReader\Metadata\Converter\Types\Detector\AttributeTypeNameDetector;
use Soap\WsdlReader\Metadata\Converter\Types\TypesConverterContext;
use function Psl\Fun\pipe;
use function Psl\Option\from_nullable;
use function Psl\Result\wrap;
use function Psl\Type\instance_of;
use function Psl\Vec\flat_map;
Expand Down Expand Up @@ -91,35 +88,15 @@ private function parseAttribute(AttributeItem $attribute, TypesConverterContext
return $this->parseAttributes($attribute, $context);
}

// Detecting the type-name for an attribute is complex.
// We first try to use the type name,
// Next up is the base type of the restriction if there aren't any restriction checks configured.
// Finally there is a fallback to the attribute name
$attributeType = $attribute instanceof AttributeSingle ? $attribute->getType() : null;
$attributeRestriction = $attributeType?->getRestriction();
$attributeTypeName = $attributeType?->getName();
$attributeRestrictionName = ($attributeRestriction && !$attributeRestriction->getChecks()) ? $attributeRestriction->getBase()?->getName() : null;

$typeName = $attributeTypeName ?: ($attributeRestrictionName ?: $attribute->getName());
$engineType = EngineType::guess($typeName);

// If a name cannot be determined from the type, we fallback to the attribute name:
// Prefix the attribute name with the parent element name resulting in a more unique type-name.
if (!$attributeTypeName && !$attributeRestrictionName) {
$engineType = AttributeDeclaringParentTypeDetector::detectWithParentContext($attribute, $context->parent())
->andThen(static fn (Type $parent): Option => from_nullable($parent->getName()))
->map(static fn (string $parentName): EngineType => $engineType->copy($parentName . ucfirst($typeName)))
->unwrapOr($engineType);
}

$typeName = (new AttributeTypeNameDetector())($attribute, $context->parent()->unwrap());
$configure = pipe(
static fn (EngineType $engineType): EngineType => (new Configurator\AttributeConfigurator())($engineType, $attribute, $context),
);

return new PropertyCollection(
new Property(
$attribute->getName(),
$configure($engineType)
$configure(EngineType::guess($typeName))
)
);
}
Expand Down

0 comments on commit b25d608

Please sign in to comment.