| Total Complexity | 43 |
| Total Lines | 504 |
| Duplicated Lines | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Complex classes like ExpandedProjectionNode 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 ExpandedProjectionNode, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 25 | class ExpandedProjectionNode extends ProjectionNode |
||
| 26 | { |
||
| 27 | /** |
||
| 28 | * An 'ExpandedProjectionNode' can represents either an expanded navigation |
||
| 29 | * property or root of the 'Projection Tree', When the node represents |
||
| 30 | * expanded navigation property this field holds reference to the resource |
||
| 31 | * (entity) set pointed by the navigation property, when the node |
||
| 32 | * represents 'Projection Tree' root, this fields holds reference to the |
||
| 33 | * resource set that the uri resource path points to. |
||
| 34 | * |
||
| 35 | * @var ResourceSetWrapper |
||
| 36 | */ |
||
| 37 | private $_resourceSetWrapper; |
||
| 38 | |||
| 39 | private $_derivedType; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * The sort information associated with the expanded navigation property or |
||
| 43 | * root of 'Projection Tree', when this node represents root of the |
||
| 44 | * projection tree then this member will be set if $top, $skip is specified |
||
| 45 | * in the request uri or server side paging is enabled for the resource |
||
| 46 | * identified by the request uri, when this node represents an expanded |
||
| 47 | * navigation property then this member will be set if server side paging |
||
| 48 | * is enabled for the resource set corresponding to the navigation |
||
| 49 | * property. |
||
| 50 | * |
||
| 51 | * @var InternalOrderByInfo |
||
| 52 | */ |
||
| 53 | private $_internalOrderByInfo; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * Number of results to be skipped for this node, the value of this field |
||
| 57 | * depends on the what this node actually represents, |
||
| 58 | * (1) Node represents navigation property |
||
| 59 | * value will be always null |
||
| 60 | * (2) Node represents root of the 'Projection Tree' |
||
| 61 | * value of the $skip query option, null if skip is absent |
||
| 62 | * A null value for this filed means return all results. |
||
| 63 | * @var int |
||
| 64 | */ |
||
| 65 | private $_skipCount; |
||
| 66 | |||
| 67 | /** |
||
| 68 | * Maximum number of results to be returned for this node, the value of |
||
| 69 | * this field depends on the what this node actually represents, |
||
| 70 | * (1) Node represents navigation property |
||
| 71 | * The page size of the resource set pointed by the navigation |
||
| 72 | * property |
||
| 73 | * (2) Node represents root of the 'Projection Tree' |
||
| 74 | * The minimum among the page size of the resource set that the |
||
| 75 | * uri resource path points to and the value of $top query option |
||
| 76 | * (if applied). |
||
| 77 | * A null value for this filed means return all results. |
||
| 78 | * |
||
| 79 | * @var int |
||
| 80 | */ |
||
| 81 | private $_takeCount; |
||
| 82 | |||
| 83 | /** |
||
| 84 | * The maximum number of results allowed for this node, taken from |
||
| 85 | * ServiceConfiguration::_maxResultsPerCollection null means no limit |
||
| 86 | * will be applied and thus all results availabe should be returned. |
||
| 87 | * |
||
| 88 | * @var int |
||
| 89 | */ |
||
| 90 | private $_maxResultCount; |
||
| 91 | |||
| 92 | /** |
||
| 93 | * List of child nodes, array of ExpandedProjectionNode and/or |
||
| 94 | * ProjectionNode. |
||
| 95 | * |
||
| 96 | * @var ProjectionNode[] |
||
| 97 | */ |
||
| 98 | private $_childNodes = array(); |
||
| 99 | |||
| 100 | /** |
||
| 101 | * When we have seen a $select path including this expanded property then |
||
| 102 | * this field will be set to true, this field is used to eliminate nodes |
||
| 103 | * representing segments in $expand option which are not selected. |
||
| 104 | * |
||
| 105 | * e.g: |
||
| 106 | * $expand=A/B, A/B/C, A/B/D, X/Y, M/N & $select=A/B |
||
| 107 | * Here we need to consider only A/B, A/B/C and A/B/D, we can eliminate |
||
| 108 | * the nodes X/Y and M/N which are not selected. This field will be set |
||
| 109 | * to true for the nodes A and B. |
||
| 110 | * |
||
| 111 | * @var boolean |
||
| 112 | */ |
||
| 113 | private $_selectionFound = false; |
||
| 114 | |||
| 115 | /** |
||
| 116 | * This field set to true when we have seen the special token '*', means |
||
| 117 | * select all immediate (child) properties of this node. |
||
| 118 | * |
||
| 119 | * e.g: |
||
| 120 | * $expand=A/B, A/B/C & $select=A/* |
||
| 121 | * Here we need to return only set of A with immediate properties, |
||
| 122 | * expand request for B, B/C will be ignored |
||
| 123 | * $expand=A/B, A/B/C & $select=* |
||
| 124 | * Here we need to return only set pointed by uri path segment with |
||
| 125 | * immediate properties, expand request be ignored |
||
| 126 | * $expand=A/B, A/B/C & $select=A/*, A/B |
||
| 127 | * Here we need to return set of A with immediate properties and |
||
| 128 | * associated B's. |
||
| 129 | * |
||
| 130 | * @var boolean |
||
| 131 | */ |
||
| 132 | private $_selectAllImmediateProperties = false; |
||
| 133 | |||
| 134 | /** |
||
| 135 | * Flag which indicate whether the entire expanded subtree of this node |
||
| 136 | * should be selected or not. |
||
| 137 | * |
||
| 138 | * e.g: |
||
| 139 | * $expand=A/B, A/B/C/D & $select=A/B |
||
| 140 | * Here need to return all immediate properties of B, associated |
||
| 141 | * C with immediate properties and associated D of C with immediate |
||
| 142 | * properties, so for B, C and D this field will be true. |
||
| 143 | * |
||
| 144 | * @var boolean |
||
| 145 | */ |
||
| 146 | private $_selectSubtree = false; |
||
| 147 | |||
| 148 | /** |
||
| 149 | * Constructs a new instance of node representing expanded navigation property |
||
| 150 | * |
||
| 151 | * @param string $propertyName The name of the property |
||
| 152 | * to expand If this node |
||
| 153 | * represents an expanded |
||
| 154 | * navigation property then |
||
| 155 | * this is the name of the |
||
| 156 | * navigation property. if this |
||
| 157 | * node represents root of the |
||
| 158 | * projection tree then this |
||
| 159 | * will be null. |
||
| 160 | * @param ResourceProperty $resourceProperty The resource property for |
||
| 161 | * the property to expand. |
||
| 162 | * If this node represents an |
||
| 163 | * expanded navigation property |
||
| 164 | * then this is the resource |
||
| 165 | * property of navigation |
||
| 166 | * property, if this node |
||
| 167 | * represents root of the |
||
| 168 | * projection tree then |
||
| 169 | * this will be null. |
||
| 170 | * @param ResourceSetWrapper $resourceSetWrapper The resource set to which |
||
| 171 | * the expansion leads, see the |
||
| 172 | * comment of _resourceSetWrapper |
||
| 173 | * field. |
||
| 174 | * @param InternalOrderByInfo $internalOrderByInfo The sort information |
||
| 175 | * associated with this node, |
||
| 176 | * see the comments of |
||
| 177 | * $_internalOrderByInfo field. |
||
| 178 | * @param int $skipCount The number of results to |
||
| 179 | * skip, null means no |
||
| 180 | * result to skip, see the |
||
| 181 | * comments of _skipCount |
||
| 182 | * field. |
||
| 183 | * @param int $takeCount The maximum number of results |
||
| 184 | * to return, null means return |
||
| 185 | * all available result, see the |
||
| 186 | * comments of _takeCount field |
||
| 187 | * @param int $maxResultCount The maximum number of |
||
| 188 | * expected result,see comment |
||
| 189 | * of _maxResultCount field |
||
| 190 | */ |
||
| 191 | public function __construct($propertyName, $resourceProperty, |
||
| 192 | ResourceSetWrapper $resourceSetWrapper, $internalOrderByInfo, |
||
| 193 | $skipCount, $takeCount, $maxResultCount, ResourceType $derivedType = null |
||
|
|
|||
| 194 | ) { |
||
| 195 | $this->_resourceSetWrapper = $resourceSetWrapper; |
||
| 196 | $this->_internalOrderByInfo = $internalOrderByInfo; |
||
| 197 | $this->_skipCount = $skipCount; |
||
| 198 | $this->_takeCount = $takeCount; |
||
| 199 | $this->_derivedType = $derivedType; |
||
| 200 | parent::__construct($propertyName, $resourceProperty); |
||
| 201 | } |
||
| 202 | |||
| 203 | /** |
||
| 204 | * Resource set to which the expansion represented by this node leads to |
||
| 205 | * (An expansion means a set of entities associated with an entity, |
||
| 206 | * associated set will be sub set of an resource set) If this node |
||
| 207 | * represents an expanded navigation property, this is the resource set |
||
| 208 | * to which the expanded navigation property points to, If this node is |
||
| 209 | * the root of projection tree, this is the resource set that the uri |
||
| 210 | * resource path points to. |
||
| 211 | * |
||
| 212 | * @return ResourceSetWrapper |
||
| 213 | */ |
||
| 214 | public function getResourceSetWrapper() |
||
| 215 | { |
||
| 216 | return $this->_resourceSetWrapper; |
||
| 217 | } |
||
| 218 | |||
| 219 | public function getDerivedType() |
||
| 220 | { |
||
| 221 | return $this->_derivedType; |
||
| 222 | } |
||
| 223 | |||
| 224 | public function setDerivedType($derivedType) |
||
| 225 | { |
||
| 226 | return $this->_derivedType = $derivedType; |
||
| 227 | } |
||
| 228 | |||
| 229 | /** |
||
| 230 | * An expansion leads by this node results in a collection of entities, |
||
| 231 | * this is the resource type of these entities, This is usually the |
||
| 232 | * resource type of the 'ResourceSetWrapper' for this node, but it can |
||
| 233 | * also be a derived type of ResourceSetWrapper::ResourceType, this can |
||
| 234 | * happen if navigation property points to a resource set but uses a |
||
| 235 | * derived type. |
||
| 236 | * |
||
| 237 | * @return ResourceType |
||
| 238 | */ |
||
| 239 | public function getResourceType() |
||
| 240 | { |
||
| 241 | return $this->resourceProperty->getResourceType(); |
||
| 242 | } |
||
| 243 | |||
| 244 | /** |
||
| 245 | * Gets array of child nodes |
||
| 246 | * |
||
| 247 | * @return ProjectionNode[]|ExpandedProjectionNode[] |
||
| 248 | */ |
||
| 249 | public function getChildNodes() |
||
| 250 | { |
||
| 251 | return $this->_childNodes; |
||
| 252 | } |
||
| 253 | |||
| 254 | /** |
||
| 255 | * Number of results to be skipped for this node, null means return all |
||
| 256 | * results, when this node represents an expanded navigation property |
||
| 257 | * then skip count will be null, If this node is the root of projection |
||
| 258 | * tree, then skip count will be value of $skip query option. |
||
| 259 | * |
||
| 260 | * @return int |
||
| 261 | */ |
||
| 262 | public function getSkipCount() |
||
| 263 | { |
||
| 264 | return $this->_skipCount; |
||
| 265 | } |
||
| 266 | |||
| 267 | /** |
||
| 268 | * Maximum number of results to be returned for this node, null means |
||
| 269 | * return all results, when this node represents an expanded navigation |
||
| 270 | * property then take count will be page size defined for the resource |
||
| 271 | * set pointed by the navigation property, If this node is the root of |
||
| 272 | * projection tree then take count will be the minimum among the page |
||
| 273 | * size of the the resource set that the uri resource path points to and |
||
| 274 | * the value of $top query option. |
||
| 275 | * |
||
| 276 | * @return int |
||
| 277 | */ |
||
| 278 | public function getTakeCount() |
||
| 279 | { |
||
| 280 | return $this->_takeCount; |
||
| 281 | } |
||
| 282 | |||
| 283 | /** |
||
| 284 | * Gets the maximum number of expected result. |
||
| 285 | * |
||
| 286 | * @return int |
||
| 287 | */ |
||
| 288 | public function getMaxResultCount() |
||
| 289 | { |
||
| 290 | return $this->_maxResultCount; |
||
| 291 | } |
||
| 292 | |||
| 293 | /** |
||
| 294 | * Gets the sort information associated with the expanded navigation |
||
| 295 | * property or root of 'Projection Tree'. |
||
| 296 | * |
||
| 297 | * @return InternalOrderByInfo|null |
||
| 298 | */ |
||
| 299 | public function getInternalOrderByInfo() |
||
| 300 | { |
||
| 301 | return $this->_internalOrderByInfo; |
||
| 302 | } |
||
| 303 | |||
| 304 | /** |
||
| 305 | * To set selection status of this node, When we have seen a $select |
||
| 306 | * path segment that selects the expanded property represented by |
||
| 307 | * this node then this function will be used to mark this node as selected. |
||
| 308 | * |
||
| 309 | * @param boolean $isSelectionFound True if selection found in this node |
||
| 310 | * False otherwise. |
||
| 311 | * |
||
| 312 | * @return void |
||
| 313 | */ |
||
| 314 | public function setSelectionFound($isSelectionFound = true) |
||
| 317 | } |
||
| 318 | |||
| 319 | /** |
||
| 320 | * To check whether this node is selected or not |
||
| 321 | * |
||
| 322 | * @return boolean |
||
| 323 | */ |
||
| 324 | public function isSelectionFound() |
||
| 325 | { |
||
| 326 | return $this->_selectionFound; |
||
| 327 | } |
||
| 328 | |||
| 329 | /** |
||
| 330 | * To set the flag indicating whether to include all immediate properties |
||
| 331 | * of this node in the result or not, When we have seen a '*' in the |
||
| 332 | * $select path segment, then this function will be used to set the flag |
||
| 333 | * for immediate properties inclusion. |
||
| 334 | * |
||
| 335 | * @param boolean $selectAllImmediateProperties True if all immediate |
||
| 336 | * properties to be included |
||
| 337 | * False otherwise. |
||
| 338 | * |
||
| 339 | * @return void |
||
| 340 | */ |
||
| 341 | public function setSelectAllImmediateProperties( |
||
| 342 | $selectAllImmediateProperties = true |
||
| 343 | ) { |
||
| 344 | $this->_selectAllImmediateProperties = $selectAllImmediateProperties; |
||
| 345 | } |
||
| 346 | |||
| 347 | /** |
||
| 348 | * To check whether immediate properties of the navigation property |
||
| 349 | * represented by this node is to be included in the result or not. |
||
| 350 | * |
||
| 351 | * @return boolean |
||
| 352 | */ |
||
| 353 | public function canSelectAllImmediateProperties() |
||
| 354 | { |
||
| 355 | return $this->_selectAllImmediateProperties; |
||
| 356 | } |
||
| 357 | |||
| 358 | /** |
||
| 359 | * Whether all child properties of this node can be selected or not, |
||
| 360 | * all child properties will be selected in 2 cases |
||
| 361 | * (1) When flag for selection of all immediate properties is true |
||
| 362 | * $select=A/B/* |
||
| 363 | * Here 'immediate properties inclusion flag' will be true for B |
||
| 364 | * (2) When flag for selection of this subtree is true |
||
| 365 | * $expand=A/B/D, A/B/C & $select = A/B |
||
| 366 | * Here 'subtree selection flag' will be true for B, C and D. |
||
| 367 | * |
||
| 368 | * @return boolean |
||
| 369 | */ |
||
| 370 | public function canSelectAllProperties() |
||
| 371 | { |
||
| 372 | return $this->_selectSubtree || $this->_selectAllImmediateProperties; |
||
| 373 | } |
||
| 374 | |||
| 375 | /** |
||
| 376 | * Find a child node with given name, if no such child node then |
||
| 377 | * return NULL. |
||
| 378 | * |
||
| 379 | * @param string $propertyName Name of the property to get the |
||
| 380 | * corresponding node. |
||
| 381 | * |
||
| 382 | * @return ProjectionNode|ExpandedProjectionNode|null |
||
| 383 | */ |
||
| 384 | public function findNode($propertyName) |
||
| 385 | { |
||
| 386 | if (array_key_exists($propertyName, $this->_childNodes)) { |
||
| 387 | return $this->_childNodes[$propertyName]; |
||
| 388 | } |
||
| 389 | |||
| 390 | return null; |
||
| 391 | } |
||
| 392 | |||
| 393 | /** |
||
| 394 | * To add a child node to the list of child nodes. |
||
| 395 | * |
||
| 396 | * @param ProjectionNode $node Node to add. |
||
| 397 | * |
||
| 398 | * @return void |
||
| 399 | * |
||
| 400 | * @throws InvalidArgumentException |
||
| 401 | */ |
||
| 402 | public function addNode($node) |
||
| 413 | } |
||
| 414 | |||
| 415 | /** |
||
| 416 | * Mark the entire subtree as selected, for example |
||
| 417 | * $expand=A/B/C/D/E & $select = A/B Here we need to select the entire |
||
| 418 | * subtree of B i.e result should include all immedate properties of B |
||
| 419 | * and associated C's, D's associated with each C and E's associated each D. |
||
| 420 | * |
||
| 421 | * @return void |
||
| 422 | */ |
||
| 423 | public function markSubtreeAsSelected() |
||
| 424 | { |
||
| 425 | $this->_selectSubtree = true; |
||
| 426 | $this->_selectAllImmediateProperties = false; |
||
| 427 | foreach ($this->_childNodes as $node) { |
||
| 428 | if ($node instanceof ExpandedProjectionNode) { |
||
| 429 | $node->markSubtreeAsSelected(); |
||
| 430 | } |
||
| 431 | } |
||
| 432 | } |
||
| 433 | |||
| 434 | /** |
||
| 435 | * Remove all child 'ExpandedProjectionNode's of this node which are |
||
| 436 | * not selected, Recursively invoke the same function for selected |
||
| 437 | * node, so that all unnecessary nodes will be removed from the subtree. |
||
| 438 | * |
||
| 439 | * @return void |
||
| 440 | */ |
||
| 441 | public function removeNonSelectedNodes() |
||
| 457 | } |
||
| 458 | } |
||
| 459 | } |
||
| 460 | } |
||
| 461 | |||
| 462 | /** |
||
| 463 | * Remove explicity included nodes which already included implicitly, For |
||
| 464 | * an expand navigation property, all immediate properties will be |
||
| 465 | * implicitly selected if that navigation property is the last segment of |
||
| 466 | * expand path or if there is a '*' token present after the naivgation |
||
| 467 | * property, this function remove all explicity included 'ProjectionNode's |
||
| 468 | * which already included implicitly. |
||
| 469 | * |
||
| 470 | * @return void |
||
| 471 | */ |
||
| 472 | public function removeNodesAlreadyIncludedImplicitly() |
||
| 499 | } |
||
| 500 | } |
||
| 501 | } |
||
| 502 | |||
| 503 | /** |
||
| 504 | * Sort the selected nodes such that order is same as the order in which |
||
| 505 | * the properties are appear in the owning type. |
||
| 506 | * |
||
| 507 | * @return void |
||
| 508 | */ |
||
| 509 | public function sortNodes() |
||
| 529 | } |
||
| 530 | } |
||
| 531 | } |
||
| 532 | } |
||
| 533 | } |
||
| 534 | } |
||
| 535 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.