CodeInstrumentationReceiver.class.php
Go to the documentation of this file.00001 <?php
00022 class CodeInstrumentationReceiver implements UmlSequenceDiagramFactoryInterface
00023 {
00029 protected static $objCodeInstrumentationReceiver;
00030
00036 protected $arrStack = array();
00037
00043 protected $arrActors = array();
00044
00050 protected $arrClasses = array();
00051
00057 protected $arrMessages = array();
00058
00064 protected $objUmlSequence = null;
00065
00071 protected $objConfiguration;
00072
00073 protected $objActualMessage;
00074
00075 protected $objActualActor;
00076
00083 public function setConfiguration( CodeInstrumentationReceiverConfiguration $objConfiguration )
00084 {
00085 $this->objConfiguration = $objConfiguration;
00086 return $this;
00087 }
00088
00094 public function getConfiguration()
00095 {
00096 return $this->objConfiguration;
00097 }
00098
00113 public function __construct()
00114 {
00115
00116 $objConfiguration = new CodeInstrumentationReceiverConfiguration();
00117 $this->setConfiguration( $objConfiguration );
00118
00119
00120 $this->objUmlSequence = new UmlSequenceDiagram();
00121
00122
00123 $objActorFrom = new UmlSequenceDiagramActor();
00124 $objActorFrom->setType( 'user' );
00125 $objActorFrom->setName( "user" );
00126 $objActorFrom->setId( sizeof( $this->arrActors ) + 1 );
00127 $this->arrActors[] = $objActorFrom;
00128 $this->arrStack[] = $objActorFrom;
00129 $this->objUmlSequence->addActor($objActorFrom);
00130 }
00131
00138 public static function getInstance()
00139 {
00140 if( self::$objCodeInstrumentationReceiver == null )
00141 {
00142 self::$objCodeInstrumentationReceiver = new CodeInstrumentationReceiver();
00143 }
00144 return self::$objCodeInstrumentationReceiver;
00145 }
00146
00162 public function renameMethod( $strMethod , $strClass )
00163 {
00164 switch( $strMethod )
00165 {
00166
00167 case "__construct":
00168 {
00169 $strMethod = ( "<<create>>" );
00170 break;
00171 }
00172
00173 case "__destruct":
00174 {
00175 $strMethod = ( "<<destroy>>" );
00176 break;
00177 }
00178
00179 default:
00180 {
00181 $objReflectedClass = new CodeReflectionClass( $strClass );
00182 $objReflectedMethod = $objReflectedClass->getMethod( $strMethod );
00183 $arrReflectedParameter = $objReflectedMethod->getParameters();
00184 $arrParams = array();
00185 foreach( $arrReflectedParameter as $objReflectedParameter )
00186 {
00187 $arrParams[] = $objReflectedParameter->getCode();
00188 }
00189 $strMethod .= "( " . implode( " , " , $arrParams ) . " )";
00190 break;
00191 }
00192 }
00193 return $strMethod;
00194 }
00195
00203 protected function shouldBeLog( $strClass , $strMethod )
00204 {
00205 if( ! $this->getConfiguration()->getActive() )
00206 {
00207 return false;
00208 }
00209
00210 if( $this->getConfiguration()->getGatekeeperClasses()->match( $strClass ) == false )
00211 {
00212 return false;
00213 }
00214
00215
00216 if( $this->getConfiguration()->getGatekeeperMethods()->match( $strMethod ) == false )
00217 {
00218 return false;
00219 }
00220
00221 return true;
00222 }
00223
00254 public function onEnterMethod( $uid , $strClassDefinition , $strMethod, $arrArguments )
00255 {
00256
00257 $strClass = CorujaClassManipulation::getClassNameFromClassDefinition( $strClassDefinition );
00258 $arrMethod = explode( "::" , $strMethod );
00259 $strRealMethod = array_pop( $arrMethod );
00260 $strMethod = $this->renameMethod( $strRealMethod , $strClass);
00261
00262
00263 $strNamespace = CorujaClassManipulation::getNamespaceFromClassDefinition( $strClassDefinition );
00264
00265 if( ! array_key_exists( $strClass, $this->arrClasses ) )
00266 {
00267 $this->arrClasses[ $strClass ] = 0;
00268 }
00269
00270
00271 if( $this->getConfiguration()->getMergeSameClassObjects() )
00272 {
00273 $uid = $strClass;
00274 }
00275
00276 if( ! $this->shouldBeLog( $strClass , $strRealMethod ) )
00277 {
00278 return $this;
00279 }
00280
00281
00282 $objActorFrom = current( $this->arrStack );
00283
00284 if( $objActorFrom === false )
00285 {
00286 return $this;
00287 }
00288
00289
00290 if( ! array_key_exists( $uid , $this->arrActors ) )
00291 {
00292
00293 $this->arrClasses[ $strClass ]++;
00294 $objActorTo = new UmlSequenceDiagramActor();
00295 $objActorTo->setStereotype( $this->getConfiguration()->getMatchGroupStereotypes()->match( $strClass ) );
00296 $objActorTo->setClassName( $strClass );
00297
00298
00299
00300 if( $this->getConfiguration()->getMergeSameClassObjects() )
00301 {
00302 $objActorTo->setName( $strClass );
00303 }
00304 else
00305 {
00306 $objActorTo->setName( $strClass . '(' . $this->arrClasses[ $strClass ] . ')');
00307 }
00308
00309 $objActorTo->setId(sizeof( $this->arrActors ) + 1 );
00310 $this->arrActors[ $uid ] = $objActorTo;
00311 $this->objUmlSequence->addActor($objActorTo);
00312 }
00313 else
00314 {
00315 $objActorTo = $this->arrActors[ $uid ];
00316 }
00317
00318 if( !$this->getConfiguration()->getIgnoreRecursiveCalls() || ( $objActorFrom != $objActorTo ) )
00319 {
00320
00321 $objMessage = new UmlSequenceDiagramMessage();
00322
00323
00324 $objMessage->setMethod( $strRealMethod );
00325 $objMessage->setText( $strMethod );
00326 $objMessage->setActorFrom( $objActorFrom );
00327 $objMessage->setActorTo( $objActorTo );
00328 $objMessage->setType( 'call' );
00329
00330 $objReflectedClass = new CodeReflectionClass( $strClass );
00331 $objReflectedMethod = $objReflectedClass->getMethod( $strRealMethod );
00332 $arrReflectedParameter = $objReflectedMethod->getParameters();
00333
00334
00335 foreach( $arrArguments as $intPos => $mixValue )
00336 {
00337 $objValue = new UmlSequenceDiagramValue();
00338 $objReflectedParameter = $arrReflectedParameter[ $intPos ];
00339 $strName = $objReflectedParameter->getName();
00340 $objValue->setName( $strName );
00341 $objValue->setValue( $mixValue );
00342 $objMessage->addValue( $objValue );
00343 }
00344 $objMessage->setTimeStart( microtime( true ) );
00345
00346
00347 $this->objUmlSequence->addMessage( $objMessage );
00348 $this->objActualMessage = $objMessage;
00349 $this->arrMessages[] = $objMessage;
00350 }
00351
00352 array_unshift( $this->arrStack , $objActorTo );
00353
00354 $this->objActualActor = $objActorFrom;
00355 return $this;
00356 }
00357
00384 public function onLeaveMethod( $uid , $strClassDefinition, $strMethod, $mixReturn )
00385 {
00386
00387 $strClass = CorujaClassManipulation::getClassNameFromClassDefinition( $strClassDefinition );
00388 $arrMethod = explode( "::" , $strMethod );
00389 $strRealMethod = array_pop( $arrMethod );
00390 $strMethod = $this->renameMethod( $strRealMethod , $strClass );
00391
00392
00393 $strNamespace = CorujaClassManipulation::getNamespaceFromClassDefinition( $strClassDefinition );
00394
00395 if( ! $this->shouldBeLog( $strClass , $strRealMethod ) )
00396 {
00397 return $this;
00398 }
00399
00400
00401 reset( $this->arrStack );
00402 $objActorFrom = array_shift( $this->arrStack );
00403
00404
00405
00406 $objActorTo = current( $this->arrStack );
00407
00408 $boolCreateMessage = true;
00409
00410 if( $mixReturn == null and $this->getConfiguration()->getIgnoreNullReturns() )
00411 {
00412 $boolCreateMessage = false;
00413 }
00414
00415 if( ( $objActorFrom == $objActorTo ) and $this->getConfiguration()->getIgnoreRecursiveCalls() )
00416 {
00417 $boolCreateMessage = false;
00418 }
00419
00420 if( $boolCreateMessage )
00421 {
00422
00423 $objMessage = new UmlSequenceDiagramMessage();
00424
00425
00426 $objMessage->setMethod( $strRealMethod );
00427 $objMessage->setText( $strMethod );
00428 $objMessage->setActorFrom( $objActorFrom );
00429 $objMessage->setActorTo( $objActorTo );
00430 $objMessage->setType( 'return' );
00431
00432
00433 if( $mixReturn !== null )
00434 {
00435 $objValue = new UmlSequenceDiagramValue();
00436 $objValue->setName( "return" );
00437 $objValue->setValue( $mixReturn );
00438 $objMessage->addValue( $objValue );
00439 }
00440
00441
00442 $this->objUmlSequence->addMessage( $objMessage );
00443 $objMessage->setTimeEnd( microtime( true ) );
00444 $this->objActualMessage = $objMessage;
00445 }
00446 $this->objActualActor = $objActorTo;
00447
00448 return $this;
00449 }
00450
00458 public function getUmlSequenceDiagram()
00459 {
00460 return $this->objUmlSequence;
00461 }
00462
00471 public function setUmlSequenceDiagram( UmlSequenceDiagram $objUmlSequence )
00472 {
00473 $this->objUmlSequence = $objUmlSequence;
00474 return $this;
00475 }
00476
00491 public function restart()
00492 {
00493
00494 $this->arrActors = array();
00495
00496 $this->arrClasses = array();
00497
00498 $this->arrMessages = array();
00499
00500 $this->arrStack = array();
00501
00502 $this->objUmlSequence->restart();
00503
00504 $this->__construct();
00505 return $this;
00506 }
00507
00513 public function perform()
00514 {
00515 return $this->getUmlSequenceDiagram();
00516 }
00517
00524 public function getActualActor()
00525 {
00526 return $this->objActualActor;
00527 }
00528
00534 public function getActualMessage()
00535 {
00536 return ( $this->objActualMessage );
00537 }
00538 }
00539
00540 ?>