Re: [argouml-dev] Some observations on java reverse engineering

Bob Tarling <[email protected]> Thu, 18 Dec 2014 10:29:33 +0000
Newsgroups gmane.comp.db.axion.devel
Message-ID <CAKWB3RRdAhXxNqq8=eo8kt2_Ln6mPgkVe9Ri-N8TQ9YoBY=NcA__1275.78609758547$1418898588$gmane$org@mail.gmail.com>
------=_Part_2295_1993433366.1418898577547
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Brilliant, thanks Thomas I'll take a look as soon as I can.

My end goal is actually to determine package dependencies. I have a large
application that I'm sure has cyclic dependencies between packages and I'd
like to demonstrate that problem to the team I work with before we tackle
how to resolve it and split the app to smaller jars.

With class dependencies in place I should be able to use that info to build
the package dependencies. I'll do that work and provide it on top of your
own.

Going back to my previous comments.... Personally I'd like to see the
creation of Components as being a checkbox option, for me that is a lot of
extra elemernts that I don't see as useful in my model

Others may view my new requirements similarly, they may prefer to have
creation of dependencies turned off so this could also be a checkbox.

A question - do you always create a dependency even if some other
relationship already exists such as an association? Again for me personally
I would only consider adding a dependency of no other relationship exists -
this could be an option if others don't share my view.

Cheers

Bob

On 17 December 2014 at 22:14, Thomas Neustupny <[email protected]> wrote:
>
> Hi Bob,
>
> here is a first attempt. First, a method call has to be added in the
> parser java.g, here:
>
> localVariableDeclaration
>     :   variableModifiers t=type
>         {
>                 // simple dependency algorithm: if t is found in the model,
>                 // then build a dependency, otherwise ignore
>             if (parserMode == MODE_IMPORT_PASS2) {
>                 getModeller().addClassifierDependency(t);
>             }
>         }
>         variableDeclarators["", (short)0, null]
>     ;
>
> Then, the method in Modeller.java has to be added, here is a first working
> version:
>
>     /**
>      * Called from the parser to add a dependency to a classifier.
>      *
>      * @param name The name of the classifier candidate.
>      */
>     void addClassifierDependency(String name) {
>         String classifierName = stripVarargAndGenerics(name);
>         Object clientObj = parseState.getClassifier();
>         if (clientObj == null) {
>             return;
>         }
>         Object supplierObj = null;
>
>         // first try: lookup classifierName in same namespace
>         Object ns = Model.getFacade().getNamespace(clientObj);
>         if (ns != null) {
>             supplierObj = Model.getFacade().lookupIn(ns, classifierName);
>         }
>
>         // second try: lookup in imports
>         if (supplierObj == null) {
>             String packageName = getPackageName(name);
>             // ...
>         }
>
>         // third try: resolve fully qualified classifier (xxx.yyy.Zzz)
>         String packageName = getPackageName(name);
>         if (supplierObj == null && packageName.length() > 0) {
>             classifierName = this.getClassifierName(name);
>             // ...
>         }
>
>         // finally build the dependency
>         if (supplierObj != null) {
>             buildDependency(supplierObj, clientObj, null);
>         }
>     }
>
> I've committed it to the Java module code, feel free to test&experiment.
> Your example already works with that provided both classes are in the same
> package.
>
> Regards,
> Thomas
>
>
> Gesendet: Montag, 15. Dezember 2014 um 21:32 Uhr
> Von: "Thomas Neustupny" <[email protected]>
> An: [email protected]
> Betreff: Aw: [argouml-dev] Some observations on java reverse engineering
> [Sorry for accidently sending in hmtl format, I'm resending it in plain
> text format]
>
>
> Hi Bob,
>
> this is no malfunction, just a missing feature. The method bodies are
> completely parsed, but the information in there is not used yet. I want
> this feature, too, and can assist. I&#39;ve just set up my dev environment
> (eclipse Luna, Java 1.8, it works well so far).
>
> The component is not generated for each class, but for each compilation
> unit (.java file), because a file can host more than one class. Also, the
> imports do not belong to the class, but to the component instance for
> obvious reasons. It&#39;s a great feature (not by me, I forgot who deserves
> the honor for that!).
>
> I suggest to identify the lines in java.g, where the type identifier for
> the associated class/interface can be found and discuss how to process
> them. The parser has two passes, so we could search the already identified
> types from the first pass during the second phase.
>
> Regards,
> Thomas
>
>
> 14 um 18:07 Uhr<br/>
> <b>Von:</b>&nbsp;&quot;Bob Tarling&quot; &lt;[email protected]
> &gt;<br/>
> <b>An:</b>&nbsp;[email protected]<br/>
> <b>Betreff:</b>&nbsp;[argouml-dev] Some observations on java reverse
> engineering</div>
>
> <div name="quoted-content">
> <div>
> <div>I&#39;m trying to generate some diagrams from an existing code base
> at work and I see some issues with the model generated.<br/>
> &nbsp;</div>
> A simple example is this.
>
> <div><br/>
> public class UseTestUtil {<br/>
> <br/>
> &nbsp;&nbsp;&nbsp; private void test() {<br/>
> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TestUtil tu = new TestUtil();<br/>
> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tu.test();<br/>
> &nbsp;&nbsp;&nbsp; }<br/>
> }<br/>
> &nbsp;</div>
>
> <div>I&#39;d expect to see a dependency relationship from UseTestUtil to
> TestUtil but nothing is generated. Is there some complication with our
> parser not being able to manage this or is this just an outstanding
> enhancement.<br/>
> &nbsp;</div>
>
> <div>I also notice a component eing generated for every class. WHy is
> this?<br/>
> &nbsp;</div>
>
> <div>Regards<br/>
> &nbsp;</div>
>
> <div>Bob<br/>
> &nbsp;</div>
>
> <div><br/>
> &nbsp;</div>
> </div>
> </div>
> </div>
> </div>
> </div></div></body></html>
>
> ------------------------------------------------------
>
> http://argouml.tigris.org/ds/viewMessage.do?dsForumId=450&dsMessageId=3092752
>
> To unsubscribe from this discussion, e-mail: [
> [email protected]].
> To be allowed to post to the list contact the mailing list moderator,
> email: [[email protected]]
>
> ------------------------------------------------------
>
> http://argouml.tigris.org/ds/viewMessage.do?dsForumId=450&dsMessageId=3092754[http://argouml.tigris.org/ds/viewMessage.do?dsForumId=450&dsMessageId=3092754]
>
> To unsubscribe from this discussion, e-mail: [
> [email protected]].
> To be allowed to post to the list contact the mailing list moderator,
> email: [[email protected]]
>
> ------------------------------------------------------
>
> http://argouml.tigris.org/ds/viewMessage.do?dsForumId=450&dsMessageId=3092933
>
> To unsubscribe from this discussion, e-mail: [
> [email protected]].
> To be allowed to post to the list contact the mailing list moderator,
> email: [[email protected]]
>

------------------------------------------------------
http://argouml.tigris.org/ds/viewMessage.do?dsForumId=450&dsMessageId=3092964

To unsubscribe from this discussion, e-mail: [[email protected]].
To be allowed to post to the list contact the mailing list moderator, email: [[email protected]]
------=_Part_2295_1993433366.1418898577547
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div><div><div><div><div><div>Brilliant, thanks Thoma=
s I&#39;ll take a look as soon as I can.<br><br></div>My end goal is actual=
ly to determine package dependencies. I have a large application that I&#39=
;m sure has cyclic dependencies between packages and I&#39;d like to demons=
trate that problem to the team I work with before we tackle how to resolve =
it and split the app to smaller jars.<br><br></div>With class dependencies =
in place I should be able to use that info to build the package dependencie=
s. I&#39;ll do that work and provide it on top of your own.<br><br></div>Go=
ing back to my previous comments.... Personally I&#39;d like to see the cre=
ation of Components as being a checkbox option, for me that is a lot of ext=
ra elemernts that I don&#39;t see as useful in my model<br><br></div>Others=
 may view my new requirements similarly, they may prefer to have creation o=
f dependencies turned off so this could also be a checkbox.<br><br></div>A =
question - do you always create a dependency even if some other relationshi=
p already exists such as an association? Again for me personally I would on=
ly consider adding a dependency of no other relationship exists - this coul=
d be an option if others don&#39;t share my view.<br><br></div>Cheers<br><b=
r></div>Bob<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On 17 December 2014 at 22:14, Thomas Neustupny <span dir=3D"ltr">&lt;<a=
 href=3D"mailto:[email protected]" target=3D"_blank">[email protected]</a>&gt;</span>=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex">Hi Bob,<br>
<br>
here is a first attempt. First, a method call has to be added in the parser=
 java.g, here:<br>
<br>
localVariableDeclaration<br>
=C2=A0 =C2=A0 :=C2=A0 =C2=A0variableModifiers t=3Dtype<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // simple dependenc=
y algorithm: if t is found in the model,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // then build a dep=
endency, otherwise ignore<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (parserMode =3D=3D MODE_IMPORT=
_PASS2) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 getModeller().addCl=
assifierDependency(t);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 variableDeclarators[&quot;&quot;, (short)0, nul=
l]<br>
=C2=A0 =C2=A0 ;<br>
<br>
Then, the method in Modeller.java has to be added, here is a first working =
version:<br>
<br>
=C2=A0 =C2=A0 /**<br>
=C2=A0 =C2=A0 =C2=A0* Called from the parser to add a dependency to a class=
ifier.<br>
=C2=A0 =C2=A0 =C2=A0*<br>
=C2=A0 =C2=A0 =C2=A0* @param name The name of the classifier candidate.<br>
=C2=A0 =C2=A0 =C2=A0*/<br>
=C2=A0 =C2=A0 void addClassifierDependency(String name) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 String classifierName =3D stripVarargAndGeneric=
s(name);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Object clientObj =3D parseState.getClassifier()=
;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (clientObj =3D=3D null) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Object supplierObj =3D null;<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 // first try: lookup classifierName in same nam=
espace<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Object ns =3D Model.getFacade().getNamespace(cl=
ientObj);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ns !=3D null) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 supplierObj =3D Model.getFacade()=
.lookupIn(ns, classifierName);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 // second try: lookup in imports<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (supplierObj =3D=3D null) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 String packageName =3D getPackage=
Name(name);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // ...<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 // third try: resolve fully qualified classifie=
r (xxx.yyy.Zzz)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 String packageName =3D getPackageName(name);<br=
>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (supplierObj =3D=3D null &amp;&amp; packageN=
ame.length() &gt; 0) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 classifierName =3D this.getClassi=
fierName(name);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // ...<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 // finally build the dependency<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (supplierObj !=3D null) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 buildDependency(supplierObj, clie=
ntObj, null);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
=C2=A0 =C2=A0 }<br>
<br>
I&#39;ve committed it to the Java module code, feel free to test&amp;experi=
ment. Your example already works with that provided both classes are in the=
 same package.<br>
<br>
Regards,=C2=A0<br>
Thomas=C2=A0<br>
<br>
<br>
Gesendet:=C2=A0Montag, 15. Dezember 2014 um 21:32 Uhr<br>
Von:=C2=A0&quot;Thomas Neustupny&quot; &lt;<a href=3D"mailto:[email protected]">=
[email protected]</a>&gt;<br>
An:=C2=A0<a href=3D"mailto:[email protected]">[email protected]</=
a><br>
Betreff:=C2=A0Aw: [argouml-dev] Some observations on java reverse engineeri=
ng<br>
<div><div class=3D"h5">[Sorry for accidently sending in hmtl format, I&#39;=
m resending it in plain text format]<br>
=C2=A0<br>
<br>
Hi Bob,<br>
<br>
this is no malfunction, just a missing feature. The method bodies are compl=
etely parsed, but the information in there is not used yet. I want this fea=
ture, too, and can assist. I&amp;#39;ve just set up my dev environment (ecl=
ipse Luna, Java 1.8, it works well so far).<br>
<br>
The component is not generated for each class, but for each compilation uni=
t (.java file), because a file can host more than one class. Also, the impo=
rts do not belong to the class, but to the component instance for obvious r=
easons. It&amp;#39;s a great feature (not by me, I forgot who deserves the =
honor for that!).<br>
<br>
I suggest to identify the lines in java.g, where the type identifier for th=
e associated class/interface can be found and discuss how to process them. =
The parser has two passes, so we could search the already identified types =
from the first pass during the second phase.<br>
<br>
Regards,<br>
Thomas<br>
<br>
<br>
14 um 18:07 Uhr&lt;br/&gt;<br>
&lt;b&gt;Von:&lt;/b&gt;&amp;nbsp;&amp;quot;Bob Tarling&amp;quot; &amp;<a hr=
ef=3D"mailto:lt%[email protected]">lt;[email protected]</a>&amp;g=
t;&lt;br/&gt;<br>
&lt;b&gt;An:&lt;/b&gt;&amp;<a href=3D"mailto:nbsp%[email protected]"=
>nbsp;[email protected]</a>&lt;br/&gt;<br>
&lt;b&gt;Betreff:&lt;/b&gt;&amp;nbsp;[argouml-dev] Some observations on jav=
a reverse engineering&lt;/div&gt;<br>
<br>
&lt;div name=3D&quot;quoted-content&quot;&gt;<br>
&lt;div&gt;<br>
&lt;div&gt;I&amp;#39;m trying to generate some diagrams from an existing co=
de base at work and I see some issues with the model generated.&lt;br/&gt;<=
br>
&amp;nbsp;&lt;/div&gt;<br>
A simple example is this.<br>
<br>
&lt;div&gt;&lt;br/&gt;<br>
public class UseTestUtil {&lt;br/&gt;<br>
&lt;br/&gt;<br>
&amp;nbsp;&amp;nbsp;&amp;nbsp; private void test() {&lt;br/&gt;<br>
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; TestUtil tu =
=3D new TestUtil();&lt;br/&gt;<br>
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; tu.test();&lt=
;br/&gt;<br>
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br/&gt;<br>
}&lt;br/&gt;<br>
&amp;nbsp;&lt;/div&gt;<br>
<br>
&lt;div&gt;I&amp;#39;d expect to see a dependency relationship from UseTest=
Util to TestUtil but nothing is generated. Is there some complication with =
our parser not being able to manage this or is this just an outstanding enh=
ancement.&lt;br/&gt;<br>
&amp;nbsp;&lt;/div&gt;<br>
<br>
&lt;div&gt;I also notice a component eing generated for every class. WHy is=
 this?&lt;br/&gt;<br>
&amp;nbsp;&lt;/div&gt;<br>
<br>
&lt;div&gt;Regards&lt;br/&gt;<br>
&amp;nbsp;&lt;/div&gt;<br>
<br>
&lt;div&gt;Bob&lt;br/&gt;<br>
&amp;nbsp;&lt;/div&gt;<br>
<br>
&lt;div&gt;&lt;br/&gt;<br>
&amp;nbsp;&lt;/div&gt;<br>
&lt;/div&gt;<br>
&lt;/div&gt;<br>
&lt;/div&gt;<br>
&lt;/div&gt;<br>
&lt;/div&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;<br>
<br>
------------------------------------------------------<br>
<a href=3D"http://argouml.tigris.org/ds/viewMessage.do?dsForumId=3D450&amp;=
dsMessageId=3D3092752" target=3D"_blank">http://argouml.tigris.org/ds/viewM=
essage.do?dsForumId=3D450&amp;dsMessageId=3D3092752</a><br>
<br>
To unsubscribe from this discussion, e-mail: [<a href=3D"mailto:dev-unsubsc=
[email protected]">[email protected]</a>].<br>
To be allowed to post to the list contact the mailing list moderator, email=
: [<a href=3D"mailto:[email protected]">[email protected]</a>]<br>
<br>
------------------------------------------------------<br>
</div></div><a href=3D"http://argouml.tigris.org/ds/viewMessage.do?dsForumI=
d=3D450&amp;dsMessageId=3D3092754[http://argouml.tigris.org/ds/viewMessage.=
do?dsForumId=3D450&amp;dsMessageId=3D3092754]" target=3D"_blank">http://arg=
ouml.tigris.org/ds/viewMessage.do?dsForumId=3D450&amp;dsMessageId=3D3092754=
[http://argouml.tigris.org/ds/viewMessage.do?dsForumId=3D450&amp;dsMessageI=
d=3D3092754]</a><br>
<span class=3D""><br>
To unsubscribe from this discussion, e-mail: [<a href=3D"mailto:dev-unsubsc=
[email protected]">[email protected]</a>].<br>
To be allowed to post to the list contact the mailing list moderator, email=
: [<a href=3D"mailto:[email protected]">[email protected]</a>]<br>
<br>
</span>------------------------------------------------------<br>
<a href=3D"http://argouml.tigris.org/ds/viewMessage.do?dsForumId=3D450&amp;=
dsMessageId=3D3092933" target=3D"_blank">http://argouml.tigris.org/ds/viewM=
essage.do?dsForumId=3D450&amp;dsMessageId=3D3092933</a><br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
To unsubscribe from this discussion, e-mail: [<a href=3D"mailto:dev-unsubsc=
[email protected]">[email protected]</a>].<br>
To be allowed to post to the list contact the mailing list moderator, email=
: [<a href=3D"mailto:[email protected]">[email protected]</a>]<br>
</div></div></blockquote></div></div>

------=_Part_2295_1993433366.1418898577547--