public function addMethod($Method) { $Operations = $this->getChild('operations'); // create new UMLMethod $Oper = new DiaUMLMethod(); $Oper->setName($Method->name()); // check @return tag $return_tags = $Method->tags('return'); if (!empty($return_tags)) { $type = $return_tags[0]->type; } else { $type = NULL; } $Oper->setType($type); // public method? if (0 == strncmp('_', $Method->name(), 1)) { $Oper->setVisibility(2); } $Oper->setComment($Method->commentText()); // check @model tags $model_tags = $Method->tags('model'); if (!empty($model_tags)) { foreach (array_keys($model_tags) as $key) { switch ($model_tags[$key]->text()) { case 'abstract': $Oper->setAbstract(TRUE); break; case 'static': $Oper->setClassScope(TRUE); break; } } } // TODO? stereotype, inheritance_type, class_scope... (@access?) // get parameters 'attribute' $Params = $Oper->getChild('parameters'); // loop over arguments foreach (array_keys($Method->arguments) as $name) { $value = $Method->arguments[$name]; // always string! if (isset($value)) { $evalue = eval("return {$value};"); if (isset($evalue)) { $type = xp::typeOf($evalue); } } else { $type = NULL; $value = NULL; } // create parameter 'composite' $Param = new DiaUMLMethodParameter(); $Param->setName($name); $Param->setValue($value); if (isset($type)) { $Param->setType($type); } // add to parameters node $Params->set($Param->getName(), $Param); } // add to operations node $Operations->set($Oper->getName(), $Oper); }
/** * Updates the given UMLClass of the diagram according to the given * ClassDoc * * @param &org.dia.DiaUMLClass Class * @param &text.doclet.ClassDoc ClassDoc */ protected function _updateClass($Class, $ClassDoc) { if (UDT_VIS_DEBUG) { Console::writeLine('* Updating class ' . $ClassDoc->qualifiedName() . '...'); } /* ClassDoc vs. DiaUMLClass... 1) delete elements from DiaUMLClass that don't exist in ClassDoc 2) loop over ClassDoc elements 3) check if element exists in DiaUMLClass - no: add - yes: update if necessary */ // get class attributes and methods $attributes = $ClassDoc->fields; $meths = $ClassDoc->methods; foreach (array_keys($meths) as $key) { $methods[$meths[$key]->name()] = $meths[$key]; } if (UDT_VIS_DEBUG) { Console::writeLine(' Class has ' . sizeof($attributes) . ' attributes...'); } // loop over UMLClass attributes (delete) $Attributes_node = $Class->getChild('attributes'); $dia_attributes = $Attributes_node->getChildByType('org.dia.DiaUMLAttribute'); foreach (array_keys($dia_attributes) as $key) { $name = $dia_attributes[$key]->getName(); if (!isset($attributes[$name])) { $Attributes_node->remChild($dia_attributes[$key]); if (UDT_VIS_DEBUG) { Console::writeLine("Attribute '{$name}': deleted..."); } continue; } $uml_attributes[$name] = $dia_attributes[$key]; } // loop over class attributes (update/add) foreach (array_keys($attributes) as $name) { if (isset($uml_attributes[$name])) { // dia attributes exists: check for update if (isset($attributes[$name])) { // value is set if ($uml_attributes[$name]->getValue() !== $attributes[$name]) { if (UDT_VIS_DEBUG) { Console::writeLine(" -> Attribute '{$name}': updated..."); } $uml_attributes[$name]->setValue($attributes[$name]); } else { if (UDT_VIS_DEBUG) { Console::writeLine(" -> Attribute '{$name}': already up-to-date..."); } } } else { // value not set if ($uml_attributes[$name]->getValue() !== '') { if (UDT_VIS_DEBUG) { Console::writeLine(" -> Attribute '{$name}': value of diagram takes precedence..."); } } else { if (UDT_VIS_DEBUG) { Console::writeLine(" -> Attribute '{$name}': value not set!"); } } } } else { // dia attribute doesn't exist: add $Attribute = new DiaUMLAttribute(); $Attribute->setName($name); $value = $attributes[$name]; if (isset($value)) { $type = xp::typeOf($value); } else { $type = NULL; $value = 'NULL'; } $Attribute->setValue($value); if (isset($type)) { $Attribute->setType($type); } // name begins with '_' if (0 == strncmp('_', substr($name, 1), 1)) { $Attribute->setVisibility(2); } if (0 == strncmp('__', $name, 2)) { $Attribute->setVisibility(1); } $Class->addUMLAttribute($Attribute); if (UDT_VIS_DEBUG) { Console::writeLine(" -> Attribute '{$name}': added..."); } } } if (UDT_VIS_DEBUG) { Console::writeLine(' Class has ' . sizeof($methods) . ' methods...'); } // loop over UMLClass methods (delete) $Operations_node = $Class->getChild('operations'); $dia_operations = $Operations_node->getChildByType('org.dia.DiaUMLMethod'); foreach (array_keys($dia_operations) as $key) { $name = $dia_operations[$key]->getName(); if (!isset($methods[$name])) { $Operations_node->remChild($dia_operations[$key]); if (UDT_VIS_DEBUG) { Console::writeLine(" => Method '{$name}': deleted..."); } continue; } $uml_methods[$name] = $dia_operations[$key]; } // loop over class methods (update/add) foreach (array_keys($methods) as $name) { if (isset($uml_methods[$name])) { // dia method exists: check for update if (UDT_VIS_DEBUG) { Console::writeLine(" => Updating existing method '{$name}'..."); } // ==> flags $Method = $uml_methods[$name]; // update return type $return_tags = $methods[$name]->tags('return'); if (!empty($return_tags)) { if ($Method->getType() !== $return_tags[0]->type) { $Method->setType($return_tags[0]->type); } } // update visibility // -> doesn't make sense, because it's determined by the method name // update comment if (($comment = $methods[$name]->commentText()) !== $Method->getComment()) { $Method->setComment($comment); } // update model (abstract/static) $model_tags = $methods[$name]->tags('model'); if (!empty($model_tags)) { // set defaults $abstract = FALSE; $class_scope = FALSE; // loop over @model tags foreach (array_keys($model_tags) as $key) { if ($model_tags[$key]->text() === 'abstract') { $abstract = TRUE; } if ($model_tags[$key]->text() === 'static') { $class_scope = TRUE; } } // update if different if ($Method->getAbstract() !== $abstract) { $Method->setAbstract($abstract); } if ($Method->getClassScope() !== $class_scope) { $Method->setClassScope($class_scope); } } // ==> parameters $Params_node = $Method->getChild('parameters'); $Params = $Params_node->getChildren(); if (UDT_VIS_DEBUG) { Console::writeLine("Params: " . xp::stringOf(array_keys($Params))); } if (UDT_VIS_DEBUG) { Console::writeLine("Args: " . xp::stringOf(array_keys($methods[$name]->arguments))); } // no arguments? delete existing parameters in diagram if (empty($methods[$name]->arguments)) { if (!empty($Params)) { // overwrite 'parameters' node with an empty one $Params_node = new DiaAttribute('parameters'); //=$Method->set('parameters', new DiaAttribute('parameters')); if (UDT_VIS_DEBUG) { Console::writeLine(" -> Parameters got deleted..."); } } else { if (UDT_VIS_DEBUG) { Console::writeLine(" -> Parameters are up-to-date..."); } } } else { // compare arguments and parameters one-by-one foreach (array_keys($methods[$name]->arguments) as $param_name) { if (UDT_VIS_DEBUG) { Console::writeLine(" -> checking argument '{$param_name}'..."); } if (!isset($Params[$param_name]) or $Params[$param_name]->getName() !== $param_name) { // replace/add parameter completely if (UDT_VIS_DEBUG) { Console::writeLine(" -> TODO:REPLACE parameter: {$param_name}..."); } } else { // update parameter (name matches) if (UDT_VIS_DEBUG) { Console::writeLine(" -> TODO:UPDATE parameter: {$param_name}..."); } } $i++; } } if (UDT_VIS_DEBUG) { Console::writeLine(" => Method '{$name}' updated..."); } } else { if (UDT_VIS_DEBUG) { Console::writeLine(" => Adding Method '{$name}'..."); } // dia method does't exist: add $Method = new DiaUMLMethod(); $Method->setName($name); // return type $return_tags = $methods[$name]->tags('return'); if (!empty($return_tags)) { $Method->setType($return_tags[0]->type); } // visibility if (0 == strncmp('_', $name, 1)) { $Method->setVisibility(2); } if (0 == strncmp('__', $name, 2)) { $Method->setVisibility(1); } // comment $Method->setComment($methods[$name]->commentText()); // model (abstract/static) $model_tags = $methods[$name]->tags('model'); if (!empty($model_tags)) { foreach (array_keys($model_tags) as $key) { if ($model_tags[$key]->text() === 'abstract') { $Method->setAbstract(TRUE); } if ($model_tags[$key]->text() === 'static') { $Method->setClassScope(TRUE); } } } // create method parameters // WEIRD: if the following is renamed to $Params it doesn't work anymore! $Params_node = $Method->getChild('parameters'); // loop over arguments foreach (array_keys($methods[$name]->arguments) as $param_name) { if (UDT_VIS_DEBUG) { Console::writeLine(" -> Adding parameter '{$param_name}'..."); } $Param = new DiaUMLMethodParameter(); $Param->setName($param_name); // type $value = $methods[$name]->arguments[$param_name]; $type = NULL; if (isset($value)) { $evalue = eval("return {$value};"); if (isset($evalue)) { $type = xp::typeOf($evalue); } } $Param->setValue($value); $Param->setType($type); // add to 'parameters' node $Params_node->set($param_name, $Param); } $Class->addUMLMethod($Method); if (UDT_VIS_DEBUG) { Console::writeLine(" => Method '{$name}': added..."); } } } $this->updated_classes[] = $ClassDoc->qualifiedName(); }