Completed
Push — master ( 852076...2b713c )
by Alex
23s queued 14s
created

ToTraceString   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
eloc 118
c 4
b 1
f 0
dl 0
loc 184
rs 5.04
wmc 57

8 Methods

Rating   Name   Duplication   Size   Complexity  
A AppendBinaryFacets() 0 11 5
A AppendDecimalFacets() 0 10 3
A AppendSpatialFacets() 0 9 2
A AppendTemporalFacets() 0 6 2
A AppendKeyValue() 0 7 1
D AppendFacets() 0 37 23
C ToTraceString() 0 48 14
B AppendStringFacets() 0 26 7

How to fix   Complexity   

Complex Class

Complex classes like ToTraceString often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ToTraceString, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace AlgoWeb\ODataMetadata\Helpers;
7
8
use AlgoWeb\ODataMetadata\EdmConstants;
9
use AlgoWeb\ODataMetadata\Enums\PrimitiveTypeKind;
10
use AlgoWeb\ODataMetadata\Enums\TypeKind;
11
use AlgoWeb\ODataMetadata\Interfaces\IBinaryTypeReference;
12
use AlgoWeb\ODataMetadata\Interfaces\ICollectionType;
13
use AlgoWeb\ODataMetadata\Interfaces\IDecimalTypeReference;
14
use AlgoWeb\ODataMetadata\Interfaces\IEdmElement;
15
use AlgoWeb\ODataMetadata\Interfaces\IEntityReferenceType;
16
use AlgoWeb\ODataMetadata\Interfaces\IPrimitiveTypeReference;
17
use AlgoWeb\ODataMetadata\Interfaces\IProperty;
18
use AlgoWeb\ODataMetadata\Interfaces\IRowType;
19
use AlgoWeb\ODataMetadata\Interfaces\ISchemaElement;
20
use AlgoWeb\ODataMetadata\Interfaces\ISpatialTypeReference;
21
use AlgoWeb\ODataMetadata\Interfaces\IStringTypeReference;
22
use AlgoWeb\ODataMetadata\Interfaces\ITemporalTypeReference;
23
use AlgoWeb\ODataMetadata\Interfaces\ITypeReference;
24
25
abstract class ToTraceString
26
{
27
    /**
28
     * Returns the text representation of the current object.
29
     *
30
     * @param  IEdmElement|null $element reference to the calling object
31
     * @return string           the text representation of the current object
32
     */
33
    public static function ToTraceString(?IEdmElement $element): string
34
    {
35
        switch (true) {
36
            case $element instanceof ISchemaElement:
37
                assert($element instanceof ISchemaElement);
38
                return $element->FullName();
39
            case $element instanceof ITypeReference:
40
                assert($element instanceof ITypeReference);
41
                $s = '[';
42
                $s .= self::ToTraceString($element->getDefinition());
43
                $s = self::AppendKeyValue(
44
                    $s,
45
                    EdmConstants::FacetName_Nullable,
46
                    $element->getNullable() ? 'TRUE' : 'FALSE'
47
                );
48
                if ($element->isPrimitive()) {
49
                    $s = self::AppendFacets($s, $element->AsPrimitive());
50
                }
51
                $s .= ']';
52
                return $s;
53
            case $element instanceof IProperty:
54
                assert($element instanceof IProperty);
55
                $type = $element->getType();
56
                return $element->getName() ?? '' . ':' . ($type !== null ? self::ToTraceString($type) :'');
57
            case $element instanceof IEntityReferenceType:
58
                assert($element instanceof IEntityReferenceType);
59
                return strval(TypeKind::EntityReference()->getKey()) . '(' . (null !== $element->getEntityType() ?
60
                        self::ToTraceString($element->getEntityType()) : '') . ')';
61
            case $element instanceof ICollectionType:
62
                assert($element instanceof ICollectionType);
63
                return strval(TypeKind::Collection()->getKey()) . '(' . (null !== $element->getElementType() ?
64
                        self::ToTraceString($element->getElementType()) : '') . ')';
65
            case $element instanceof IRowType:
66
                assert($element instanceof IRowType);
67
                $s = TypeKind::Row()->getKey();
68
                $s .= '(';
69
                foreach ($element->Properties() as $prop) {
70
                    if (null === $prop) {
71
                        continue;
72
                    }
73
                    $s .= self::ToTraceString($prop);
74
                    $s .= ', ';
75
                }
76
                $s = substr($s, 0, -2);
77
                $s .= ')';
78
                return $s;
79
            default:
80
                return EdmConstants::Value_UnknownType;
81
        }
82
    }
83
84
    private static function AppendFacets(string $s, IPrimitiveTypeReference $type): string
85
    {
86
        switch ($type->PrimitiveKind()) {
87
            case PrimitiveTypeKind::Binary():
88
                $s = self::AppendBinaryFacets($s, $type->AsBinary());
89
                break;
90
            case PrimitiveTypeKind::Decimal():
91
                $s = self::AppendDecimalFacets($s, $type->AsDecimal());
92
                break;
93
            case PrimitiveTypeKind::String():
94
                $s = self::AppendStringFacets($s, $type->AsString());
95
                break;
96
            case PrimitiveTypeKind::Time():
97
            case PrimitiveTypeKind::DateTime():
98
            case PrimitiveTypeKind::DateTimeOffset():
99
                $s = self::AppendTemporalFacets($s, $type->AsTemporal());
100
                break;
101
            case PrimitiveTypeKind::Geography():
102
            case PrimitiveTypeKind::GeographyPoint():
103
            case PrimitiveTypeKind::GeographyLineString():
104
            case PrimitiveTypeKind::GeographyPolygon():
105
            case PrimitiveTypeKind::GeographyCollection():
106
            case PrimitiveTypeKind::GeographyMultiPoint():
107
            case PrimitiveTypeKind::GeographyMultiLineString():
108
            case PrimitiveTypeKind::GeographyMultiPolygon():
109
            case PrimitiveTypeKind::Geometry():
110
            case PrimitiveTypeKind::GeometryPoint():
111
            case PrimitiveTypeKind::GeometryLineString():
112
            case PrimitiveTypeKind::GeometryPolygon():
113
            case PrimitiveTypeKind::GeometryCollection():
114
            case PrimitiveTypeKind::GeometryMultiPolygon():
115
            case PrimitiveTypeKind::GeometryMultiLineString():
116
            case PrimitiveTypeKind::GeometryMultiPoint():
117
                $s = self::AppendSpatialFacets($s, $type->AsSpatial());
118
                break;
119
        }
120
        return $s;
121
    }
122
123
124
    private static function AppendBinaryFacets(string $sb, IBinaryTypeReference $type): string
125
    {
126
        self::AppendKeyValue($sb, EdmConstants::FacetName_FixedLength, $type->isFixedLength() ? 'TRUE' : 'FALSE');
127
        if ($type->isUnBounded() || null !== $type->getMaxLength()) {
128
            $sb = self::AppendKeyValue(
129
                $sb,
130
                EdmConstants::FacetName_MaxLength,
131
                ($type->isUnBounded()) ? EdmConstants::Value_Max : strval($type->getMaxLength())
132
            );
133
        }
134
        return $sb;
135
    }
136
137
    private static function AppendStringFacets(string $sb, IStringTypeReference $type): string
138
    {
139
        if (true === $type->isFixedLength()) {
140
            $sb = self::AppendKeyValue(
141
                $sb,
142
                EdmConstants::FacetName_FixedLength,
143
                'TRUE'
144
            );
145
        }
146
147
        if (true === $type->isUnbounded() || null !== $type->getMaxLength()) {
148
            $sb = self::AppendKeyValue(
149
                $sb,
150
                EdmConstants::FacetName_MaxLength,
151
                $type->isUnbounded() ? EdmConstants::Value_Max : $type->getMaxLength()
152
            );
153
        }
154
155
        if (true === $type->isUnicode()) {
156
            $sb = self::AppendKeyValue($sb, EdmConstants::FacetName_Unicode, 'TRUE');
157
        }
158
159
        if (null !== $type->getCollation()) {
160
            $sb = self::AppendKeyValue($sb, EdmConstants::FacetName_Collation, $type->getCollation());
161
        }
162
        return $sb;
163
    }
164
165
    private static function AppendTemporalFacets(string $sb, ITemporalTypeReference $type): string
166
    {
167
        if (null !== $type->getPrecision()) {
168
            $sb = self::AppendKeyValue($sb, EdmConstants::FacetName_Precision, $type->getPrecision());
169
        }
170
        return $sb;
171
    }
172
173
    private static function AppendDecimalFacets(string $sb, IDecimalTypeReference $type): string
174
    {
175
        if (null !== $type->getPrecision()) {
176
            $sb = self::AppendKeyValue($sb, EdmConstants::FacetName_Precision, $type->getPrecision());
177
        }
178
179
        if (null !== $type->getScale()) {
180
            $sb = self::AppendKeyValue($sb, EdmConstants::FacetName_Scale, $type->getScale());
181
        }
182
        return $sb;
183
    }
184
185
    private static function AppendSpatialFacets(string $sb, ISpatialTypeReference $type): string
186
    {
187
        $sb = self::AppendKeyValue(
188
            $sb,
189
            EdmConstants::FacetName_Srid,
190
            null !== $type->getSpatialReferenceIdentifier()
191
                ? $type->getSpatialReferenceIdentifier(): EdmConstants::Value_SridVariable
192
        );
193
        return $sb;
194
    }
195
196
    /**
197
     * @param  string          $s
198
     * @param  string          $key
199
     * @param  string|int|null $value
200
     * @return string
201
     */
202
    private static function AppendKeyValue(string $s, string $key, $value)
203
    {
204
        $s .= ' ';
205
        $s .= $key;
206
        $s .= '=';
207
        $s .= $value;
208
        return $s;
209
    }
210
}
211