3 /* vim: set binary expandtab tabstop=4 shiftwidth=4 foldmethod=marker:
4 -------------------------------------------------------------------------------
5 Creado: jue jul 31 14:01:57 ART 2003
6 Autor: Martin Marrese <mmarre@mecon.gov.ar>
7 -------------------------------------------------------------------------------
9 -----------------------------------------------------------------------------*/
11 //Recibe como parametros el directorio o una lista de archivos a diagramar
15 <?xml version="1.0" encoding="UTF-8"?>
16 <XMI xmlns:UML="org.omg/standards/UML" verified="false" timestamp="" xmi.version="1.2" >
23 <listitem open="1" type="800" id="-1" label="Views" >
24 <listitem open="1" type="801" id="-1" label="Logical View" >
28 <listitem open="1" type="802" id="-1" label="Use Case View" />
29 <listitem open="1" type="821" id="-1" label="Component View" />
30 <listitem open="1" type="827" id="-1" label="Deployment View" />
31 <listitem open="0" type="823" id="-1" label="Diagrams" />
38 //LINEAS TEMPLATES XMI {{{
39 $umlclass = '<UML:Class stereotype="##STEREOTYPE##" package="##PACKAGE##" xmi.id="##ID##" abstract="##ABSTRACT##" documentation="##DOCUMENTATION##" name="##NAME##" static="##STATIC##" scope="##SCOPE##" >';
40 $umlclass_c = '</UML:Class>';
42 $umloperation = '<UML:Operation stereotype="##STEREOTYPE##" package="##PACKAGE##" xmi.id="##ID##" type="##TYPE##" abstract="##ABSTRACT##" documentation="##DOCUMENTATION##" name="##NAME##" static="##STATIC##" scope="##SCOPE##">';
43 $umloperation_c = '</UML:Operation>';
45 $umlparameter = '<UML:Parameter stereotype="##STEREOTYPE##" package="##PACKAGE##" xmi.id="##ID##" value="##VALUE##" type="##TYPE##" abstract="##ABSTRACT##" documentation="##DOCUMENTATION##" name="##NAME##" static="##STATIC##" scope="##SCOPE##" />';
47 $umlattribute = '<UML:Attribute stereotype="##STEREOTYPE##" package="##PACKAGE##" xmi.id="##ID##" value="##VALUE##" type="##TYPE##" abstract="##ABSTRACT##" documentation="##DOCUMENTATION##" name="##NAME##" static="##STATIC##" scope="##SCOPE##" />';
49 $umllistitem = '<listitem open="0" type="##TYPE##" id="##ID##" label="##LABEL##" >';
50 $umllistitem_c = '</listitem>';
52 //VARIABLES GLOBALES {{{
58 //CHUPO LA INFO DE LOS ARCHIVOS {{{
59 for ($j = 1; $j < count($argv); $j++) {
61 //ARMO LA LISTA DE ARCHIVOS {{{
62 // Si es un directorio, agrego cada archivo legible .php al argv.
65 while (($f = readdir($dh)) !== false) {
66 if (is_readable("$file/$f") and substr($f, -4) == '.php') {
75 elseif (is_readable($file) and substr($file, -4) == '.php') {
77 $DOCUMENTANDO = false;
80 foreach ($cont as $linea) {
81 $linea = trim ($linea);
82 $tmp = preg_split ('/[^\w_\/\*\@\$\&\.\']+/', $linea);
84 if ($tmp['0'] == '/**') { //Comienza la documentacion
88 if ($tmp['0'] == '*/') { //Termina la documentacion
89 $DOCUMENTANDO = false;
95 $tmp2 = ltrim ($linea,'* /**'); //Elimino el * o /** del comienzo de la linea
96 $accion = substr($tmp2, 0, strpos($tmp2,' ')); //Obtengo la accion
97 $accion = ($accion === '') ? $tmp2 : $accion;
98 $value = trim(strstr($tmp2, ' ')); //Solo me importa lo que esta detras del @
101 case '@access' : switch ($value) {
102 case 'private' : $opciones['access'] = 201;
104 case 'protected': $opciones['access'] = 202;
106 default : $opciones['access'] = 200;
110 case '@package' : $opciones['package'] = $value;
113 case '@abstract': $opciones['abstract'] = 1;
116 case '@static' : $opciones['static'] = 1;
119 case '@var' : $opciones['type'] = substr($value, 0, strpos($value,' '));
122 case '@return' : $type = substr($value, 0, strpos($value,' '));
123 $resto = (strpos($value,' ')) ? substr($value, strpos($value,' ')) : '';
127 if (strtolower($type) == 'object') {
128 $resto = trim($resto);
129 $type = substr($resto, 0, strpos($resto,' '));
130 $resto = (strpos($resto,' ')) ? substr($resto, strpos($resto,' ')) : '';
132 $opciones['type'] = $type;
134 $opciones['documentacion'].= "Returns: ".trim($resto);
139 case '@param' : $cont_param++;
140 $type = substr($value, 0, strpos($value,' '));
141 $resto = substr($value, strpos($value,' ') + 1);
142 if (strtolower($type) == 'object') {
143 $resto = trim($resto);
144 $type = substr($resto, 0, strpos($resto,' '));
145 $resto = substr($resto, strpos($resto,' ') + 1);
147 $opciones['param'][$cont_param]['type'] = $type;
148 $opciones['param'][$cont_param]['documentacion'] = trim(substr(trim($resto), strpos(trim($resto), ' ')));
152 $tmp2 = str_replace('"', '"', $tmp2);
153 $tmp2 = str_replace('<', '<' , $tmp2);
154 $tmp2 = str_replace('>', '>' , $tmp2);
155 $tmp2 = str_replace('&', '&' , $tmp2);
157 $opciones['param'][$cont_param]['documentacion'].= "\n".$tmp2;
160 @$opciones['documentacion'].= $tmp2."\n";
167 if (!$DOCUMENTANDO && $tmp['0'] == 'class') {
171 $ARRAY[$ID]['id'] = $ID;
172 $ARRAY[$ID]['name'] = $tmp['1'];
173 $ARRAY[$ID]['stereotype'] = (@$opciones['stereotype']) ? $opciones['stereotype'] : '';
174 $ARRAY[$ID]['package'] = (@$opciones['package']) ? $opciones['package'] : '';
175 $ARRAY[$ID]['abstract'] = (@$opciones['abstract']) ? $opciones['abstract'] : 0;
176 $ARRAY[$ID]['documentation'] = (@$opciones['documentacion']) ? $opciones['documentacion'] : '';
177 $ARRAY[$ID]['static'] = (@$opciones['static']) ? $opciones['static'] : 0;
178 $ARRAY[$ID]['scope'] = (@$opciones['access']) ? $opciones['access'] : 200;
179 $ARRAY[$ID]['operations'] = array();
180 $ARRAY[$ID]['attributes'] = array();
185 if (!$DOCUMENTANDO && $tmp['0'] == 'function') {
188 if ($tmp['1']{0} == '&') {
189 $tmp['1'] = substr($tmp['1'], 1); //SACO EL &
190 $opciones['type'] = (@$opciones['type']) ? '&'.$opciones['type'] : '';
193 if ($tmp['1']{0} == '_') {
194 $tmp['1'] = substr($tmp['1'], 1); //SACO EL _
196 $ARRAY[$IDCLASE]['operations'][$ID]['id'] = $ID;
197 $ARRAY[$IDCLASE]['operations'][$ID]['name'] = $tmp['1'];
198 $ARRAY[$IDCLASE]['operations'][$ID]['stereotype'] = (@$opciones['stereotype']) ? $opciones['stereotype'] : '';
199 $ARRAY[$IDCLASE]['operations'][$ID]['package'] = (@$opciones['package']) ? $opciones['package'] : '';
200 $ARRAY[$IDCLASE]['operations'][$ID]['abstract'] = (@$opciones['abstract']) ? $opciones['abstract'] : 0;
201 $ARRAY[$IDCLASE]['operations'][$ID]['documentation'] = (@$opciones['documentacion']) ? $opciones['documentacion'] : '';
202 $ARRAY[$IDCLASE]['operations'][$ID]['static'] = (@$opciones['static']) ? $opciones['static'] : 0;
203 $ARRAY[$IDCLASE]['operations'][$ID]['scope'] = (@$opciones['access']) ? $opciones['access'] : 200;
204 $ARRAY[$IDCLASE]['operations'][$ID]['type'] = (@$opciones['type']) ? $opciones['type'] : '';
205 $ARRAY[$IDCLASE]['operations'][$ID]['param'] = array();
208 $param_line = trim(substr(strstr($linea,'('),0),'{ '); //Saco la ultima {
209 $param = parseParentesis($param_line);
211 foreach ($param as $par) {
212 if ($par['name']{0} == '$'|| $par['name']{0} == '&') { //Veo si empiezo con $ o &
213 switch ($par['name']{0}) {
214 case '$': $par['name'] = substr($par['name'], 1); //SACO EL $
216 case '&': $par['name'] = substr($par['name'], 2); //SACO EL & Y EL $
217 $opciones['param'][$i]['type'] =
218 (@$opciones['param'][$i]['type']) ? '&'.$opciones['param'][$i]['type'] : '';
221 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['id'] = $i;
222 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['name'] = $par['name'];
223 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['stereotype'] =
224 (@$opciones['param'][$i]['stereotype']) ? $opciones['param'][$i]['stereotype'] : '';
226 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['package'] =
227 (@$opciones['param'][$i]['package']) ? $opciones['param'][$i]['package'] : '';
229 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['abstract'] =
230 (@$opciones['param'][$i]['abstract']) ? $opciones['param'][$i]['abstract'] : 0;
232 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['documentation'] =
233 (@$opciones['param'][$i]['documentacion']) ? $opciones['param'][$i]['documentacion'] : '';
235 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['static'] =
236 (@$opciones['param'][$i]['static']) ? $opciones['param'][$i]['static'] : 0;
238 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['scope'] =
239 (@$opciones['param'][$i]['access']) ? $opciones['param'][$i]['access'] : '';
241 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['type'] =
242 (@$opciones['param'][$i]['type']) ? $opciones['param'][$i]['type'] : '';
244 $ARRAY[$IDCLASE]['operations'][$ID]['param'][$i]['value'] =
245 (@$par['value']) ? $par['value'] : '';
256 if (!$DOCUMENTANDO && $tmp['0'] == 'var') {
258 $tmp['1'] = substr($tmp['1'], 1); //SACO EL $
259 if ($tmp['1']{0} == '_') {
260 $tmp['1'] = substr($tmp['1'],1); //SACO EL _
261 if (!(@$opciones['access'])) {
262 $opciones['access'] = 201;
265 //Agrego si tiene valor inicial
266 if (array_key_exists('2',$tmp)) {
267 $opciones['value'] = $tmp['2'];
270 $ARRAY[$IDCLASE]['attributes'][$ID]['id'] = $ID;
271 $ARRAY[$IDCLASE]['attributes'][$ID]['name'] = $tmp['1'];
272 $ARRAY[$IDCLASE]['attributes'][$ID]['stereotype'] = (@$opciones['stereotype']) ? $opciones['stereotype'] : '';
273 $ARRAY[$IDCLASE]['attributes'][$ID]['package'] = (@$opciones['package']) ? $opciones['package'] : '';
274 $ARRAY[$IDCLASE]['attributes'][$ID]['abstract'] = (@$opciones['abstract']) ? $opciones['abstract'] : 0;
275 $ARRAY[$IDCLASE]['attributes'][$ID]['documentation'] = (@$opciones['documentacion']) ? $opciones['documentacion'] : '';
276 $ARRAY[$IDCLASE]['attributes'][$ID]['static'] = (@$opciones['static']) ? $opciones['static'] : 0;
277 $ARRAY[$IDCLASE]['attributes'][$ID]['scope'] = (@$opciones['access']) ? $opciones['access'] : 200;
278 $ARRAY[$IDCLASE]['attributes'][$ID]['type'] = (@$opciones['type']) ? $opciones['type'] : '';
279 $ARRAY[$IDCLASE]['attributes'][$ID]['value'] = (@$opciones['value']) ? $opciones['value'] : '';
290 //GUARDO EN EL ARCHIVO {{{
291 $m =fopen ('./umlOut.xmi', 'w');
292 fwrite($m, $comienzo);
295 foreach ($ARRAY as $ar) {
298 fwrite($m, preg_replace (array ('/##STEREOTYPE##/','/##PACKAGE##/','/##ID##/','/##ABSTRACT##/','/##DOCUMENTATION##/','/##NAME##/',
299 '/##STATIC##/','/##SCOPE##/'),
300 array ($ar['stereotype'],$ar['package'],$ar['id'],$ar['abstract'],trim($ar['documentation']),$ar['name'],
301 $ar['static'],$ar['scope']),
303 //PREPARO LOS LISTITEM
304 $tmp2 = $umllistitem;
305 $LISTITEM.= preg_replace (array('/##TYPE##/','/##LABEL##/','/##ID##/'),array(813, $ar['name'], $ar['id']),$tmp2)."\n";
308 foreach ($ar['operations'] as $op) {
309 $tmp2 = $umloperation;
310 fwrite($m, preg_replace (array('/##STEREOTYPE##/','/##PACKAGE##/','/##ID##/','/##TYPE##/','/##ABSTRACT##/','/##DOCUMENTATION##/',
311 '/##NAME##/','/##STATIC##/','/##SCOPE##/'),
312 array($op['stereotype'],$op['package'],$op['id'],$op['type'],$op['abstract'],trim($op['documentation']),
313 $op['name'],$op['static'],$op['scope']) ,
315 //PARAMETROS NO TIENE LISTITEM
316 foreach ($op['param'] as $pa) {
317 $tmp2 = $umlparameter;
318 fwrite ($m, preg_replace(array('/##STEREOTYPE##/','/##PACKAGE##/','/##ID##/','/##TYPE##/','/##ABSTRACT##/','/##DOCUMENTATION##/',
319 '/##NAME##/','/##STATIC##/','/##SCOPE##/','/##VALUE##/'),
320 array($pa['stereotype'],$pa['package'],$pa['id'],$pa['type'],$pa['abstract'],trim($pa['documentation']),
321 $pa['name'],$pa['static'],$pa['scope'],$pa['value']),
324 fwrite($m,$umloperation_c."\n");
325 //PREPARO LOS LISTITEM
326 $tmp2 = $umllistitem;
327 $LISTITEM.= preg_replace (array('/##TYPE##/','/##LABEL##/','/##ID##/'),array(815, $op['name'], $op['id']),$tmp2)."\n";
328 $LISTITEM.=$umllistitem_c."\n";
331 foreach ($ar['attributes'] as $op) {
332 $tmp2 = $umlattribute;
333 fwrite($m, preg_replace(array('/##STEREOTYPE##/','/##PACKAGE##/','/##ID##/','/##TYPE##/','/##ABSTRACT##/','/##DOCUMENTATION##/',
334 '/##NAME##/','/##STATIC##/','/##SCOPE##/','/##VALUE##/'),
335 array($op['stereotype'],$op['package'],$op['id'],$op['type'],$op['abstract'],trim($op['documentation']),$op['name'],
336 $op['static'],$op['scope'],$op['value']),
338 //PREPARO LOS LISTITEM
339 $tmp2 = $umllistitem;
340 $LISTITEM.= preg_replace (array('/##TYPE##/','/##LABEL##/','/##ID##/'),array(814, $op['name'], $op['id']),$tmp2)."\n";
341 $LISTITEM.=$umllistitem_c."\n";
343 fwrite($m,$umlclass_c);
344 $LISTITEM.=$umllistitem_c."\n";
346 fwrite($m, $medio. $LISTITEM."\n".$fin);
354 //PARSER_PARENTESIS {{{
355 //Funcion que parsea por el contenido entre parentesis
356 //Devuelve un array de arrays
357 function parseParentesis($value) {
362 $value = substr(substr(trim($value), 1), 0, strrpos(substr(trim($value), 1),')'));
365 //Busco la siguiente separacion ( , o = ) {{{
366 if (!strpos($value, ',') && !strpos($value, '=')) {
369 elseif (!strpos($value, ',') && strpos($value, '=')) {
370 if ($value{strpos($value, '=') + 1} == '>') {
377 elseif (strpos($value, ',') && !strpos($value, '=')) {
380 elseif (strpos($value, ',') && strpos($value, '=') && strpos($value, ',') > strpos($value, '=')) {
381 if ($value{strpos($value, '=') + 1} == '>') {
388 elseif (strpos($value, ',') && strpos($value, '=') && strpos($value, ',') < strpos($value, '=')) {
393 //Obtengo el nombre a partir del caracter de separacion {{{
394 $result[$pos]['name'] = (strpos($value, $char)) ? substr($value, 0, strpos($value, $char)) : $value;
395 $pos_del = strpos($value, $char);
398 //Busco el valor asociado {{{
400 $op_value = (strpos($value, $char)) ? trim(substr($value, strpos($value, $char) + 1)) : false;
402 elseif ($char == '=>') {
403 $op_value = (strpos($value, $char)) ? trim(substr($value, strpos($value, $char) + 2)) : false;
407 //Parseo el resto de la linea {{{
409 if ($op_value{0} == "'" || $op_value{0} == '"') {
410 $pos_del = parseComillas($op_value);
412 $result[$pos]['value'] = "''";
415 $op_value = substr($op_value, 1);
416 $result[$pos]['value'] = substr($op_value, 0, $pos_del);
419 elseif (trim(strtolower(substr($op_value, 0 ,5))) == 'array') { //RECURSIVIDAD {{{
420 $op_value = trim(substr($op_value, 5));
421 $op_value = trim(substr($op_value, 1)); //Saco el (
423 if ($op_value{0} == ')') {
424 $result[$pos]['value'] = 'array()';
427 //Busco a manopla el ) que cierra el array(##ALGO##) {{{
432 if (($temp{$subpos} == '"' || $temp{$subpos} == "'") && $temp{$subpos - 1} != '\\') {
433 $pos_del = parseComillas(substr($temp,$subpos)) + $subpos;
434 $subpos = $pos_del + 2;
436 if (trim($temp{$subpos}) == ')') {
441 if ($subpos > strlen($temp)) {
448 $par = parseParentesis('('.substr($op_value, 0 , $subpos).')');
449 $result[$pos]['value'] = 'array(';
450 foreach ($par as $p) {
451 $result[$pos]['value'] .= $p['name'];
453 $result[$pos]['value'] .= '=>\''.$p['value'].'\',';
456 $result[$pos]['value'] .= ',';
459 $result[$pos]['value'] = rtrim($result[$pos]['value'],',');
460 $result[$pos]['value'] .= ')';
465 //Busco la , de separacion con el proximo parametro
466 //en caso de ser el utlimo lo asigno como viene
467 if ($pos_del = strpos($op_value, ',')) {
468 $result[$pos]['value'] = ($pos_del) ? trim(substr($op_value, 0, $pos_del)): $op_value;
475 //Borro de $value lo que ya parsee {{{
477 $value = trim(substr(trim($value), $pos_del + 2));
489 //PARSER_COMILLAS {{{
490 //Funcion que parsea por el contenido entre comillas
491 //Devuelve la pos de la ' que cierra el comentario
492 function parseComillas($value) {
496 switch ($value{0}) { //{{{
504 $value = substr($value, 1); //Saco la ' o " del comienzo del string
505 if ($value{0} == $char) {
509 while ($cont) { //{{{
511 if ($value{$ii} == $char) {
512 if ($value{$ii - 1} != '\\') {