jdepend-2.9.1/0000755000000000000000000000000010236624042011631 5ustar rootrootjdepend-2.9.1/CHANGES0000644000000000000000000001472210236624040012630 0ustar rootrootJDepend Change Log Version 2.9.1 - 5/6/05 ---------------------- - Fixed the GUI runner to support the -components option. Version 2.9 - 12/27/04 ---------------------- - Includes the Module Dependencies fixture for FitNesse, contributed by Bob Martin. Thanks, Bob! (See http://www.butunclebob.com/ArticleS.UncleBob.JdependFixture) - Declared components now include an implicit trailing ".". For example, if you want to treat all sub-packages beneath the "com.foo" package as a component, use java jdepend.textui.JDepend -components com.foo /path/to/classes or, programmatically, use jdepend.setComponents("com.foo"); Note, however, that an implicit "." will be appended ("com.foo."), which means that the package "com.foobar", for example, will NOT be included in the "com.foo" component. - Added a version number to the JAR file. Version 2.8 - 9/2/04 -------------------- - Components can now be defined using the -components option to any JDepend user interface. - Added the Graphviz stylesheet (contrib/jdepend2dot.xsl) to transform the JDepend XML format into the Graphviz dot file format. (Contributed by David Bock.) - Fixed a minor bug related to using the exclude tag with the JDepend Ant task. - Fixed a minor bug that was exhausting file descriptors for large (2000+) file sets. Version 2.7 - 4/10/04 --------------------- - Set UTF-8 as the output encoding for the XML output so that the XML file generated is valid if the data contains non-ASCII characters. (Thanks to Olivier Mengue.) Version 2.6 - 2/19/04 (Somewhere between Denver and Austin) ----------------------------------------------------------- - Classes in .jar, .war, and .zip files are now analyzed. - Added JavaPackage.collectAllCycles() to support the Eclipse plugin and to start experimenting with more exhaustive cycle detection techniques. Version 2.5 - 2/17/03 --------------------- - Source-file analysis is no longer supported. - Inner classes are now analyzed by default. To disable analyzing inner classes, set the 'analyzeInnerClasses' property to 'false' in the jdepend.properties file. - Added setFilter() method to all JDepend class variants to support new JDepend Ant task which includes an element for excluding packages. (Thanks to Bob Hays for updating the Ant task!) - Added JavaClass.getSourceFile() method which returns the name of the source file from which the analyzed class file was generated. Source files must be compiled with debug information (e.g. -g or -g:source), otherwise "Unknown" is returned. (Thanks to Ben Walding for contributing this code!) Version 2.4 - 2/5/03 -------------------- - Source-file analysis is now deprecated. Please adjust to using class-file analysis by simply pointing JDepend at directories containing class files. The next version will not support the analysis of source files. - Added support for presetting a volatility (V) value on a package-by-package basis. - Unzips into versioned directory. Version 2.3 - 1/3/03 -------------------- - Removed java.* and javax.* from the default package filter. By default, no packages are filtered. - Added a constructor to jdepend.framework.JDepend that takes a PackageFilter parameter. Filters can now be applied by using this constructor or by creating a jdepend.properties file in the classPATH (see samples/jdepend.properties). - Fixed several bugs related to properly identifying class and interface names when parsing source files. - Fixed bug parsing java.lang.Object - Modified jdepend.xmlui.JDepend to always generate XML for the English locale so that '.' is used as the decimal separator. XML Schema identifies a float with a mandatory '.'. XSL is unable to transform decimal separators other than ".". - Reorganized directory structure to include top-level 'src' and 'tests' directories. Version 2.2 - 10/25/01 ---------------------- - Removed validation of major/minor class file versions during class file parsing to support Java 1.4 and beyond. - Added "Interpreting Dependency Cycles" section to documentation. - Clean-up of build.xml for consistency and added example use of JDepend Ant task. Version 2.1 - 8/6/01 -------------------- - When parsing class files, constant pool class constants that refer to array types are now properly parsed. - When parsing source files, leading spaces are now properly parsed for package names, imports, and class declarations. Version 2.0 - 8/1/01 -------------------- - Added support for parsing class files in addition to source files. Class file parsing is more accurate in its ability to identify referenced packages not directly visible from 'package' or 'import' statements. Analyzed package references include super classes, implemented interfaces, class attribute types, method return types, method parameter types, method exception types, and method local variable types. If a given directory contains both a source file and a class file for the same Java class, then the class file is analyzed and the source file is ignored. Class files must exist in a directory; JAR files are not supported in this release. Version 1.4 - 7/20/01 --------------------- - Added package dependency constraints to support writing tests that fail if any package dependency other than those declared in the dependency constraints are detected. - Added the jdepend.xmlui.JDepend class to generate the package metrics, dependencies, and cycles in an XML format for easier integration with other tools. Version 1.3 - 7/5/01 -------------------- - Package dependency cycles can now detected and the packages participating in a package dependency cycle can be traversed. By default, the textual UI prints the hierarchical paths of each package dependency cycle and the graphical UI marks any packages containing cyclic package dependencies with a "Cyclic" label. - DistanceExampleTest was renamed to ExampleTest, which now also contains example JUnit test methods for automatically checking for the existence of package dependency cycles. Version 1.2 - 5/11/01 --------------------- - Recognition of 'final' and 'strictfp' class modifiers. - Trim extra whitespace from imports and class name declaration. - Ignore trailing comments from class name declaration. - Add delegating addDirectory() method to the jdepend.textui.JDepend and jdepend.swingui.JDepend classes. - Improved command-line error handling. Version 1.1 - 1/25/01 --------------------- - Initial public release. jdepend-2.9.1/LICENSE0000644000000000000000000000306410236624040012637 0ustar rootrootCopyright (C) 1999-2004 Clarkware Consulting, Inc. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of Clarkware Consulting, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact clarkware@clarkware.com. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jdepend-2.9.1/README0000644000000000000000000000212110236624040012503 0ustar rootroot J D E P E N D What Is It? ----------- JDepend traverses Java class and source file directories and generates design quality metrics for each Java package. JDepend allows you to automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to effectively manage and control package dependencies. How Do I Get It? ---------------- The latest version of JDepend is available at http://www.clarkware.com/software/jdepend.zip Documentation ------------- Documentation is available in HTML format, in the docs/ directory. For the installation and user manual, see docs/JDepend.html. For the API documentation, see docs/api/index.html. Support --------- If you have any questions, comments, enhancement requests, success stories, or bug reports regarding JDepend, please send them to mike@clarkware.com. Licensing --------- This software is licensed under the terms described in the file named "LICENSE" in this directory. Thanks for using JDepend! jdepend-2.9.1/contrib/0000755000000000000000000000000010236624042013271 5ustar rootrootjdepend-2.9.1/contrib/jdepend2dot.xsl0000644000000000000000000000375310236624042016233 0ustar rootroot digraph g { graph [ rankdir = "LR" ]; node [ fontsize = "12" fontname = "Courier" shape = "ellipse" ]; edge[]; } " " [ label=" | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; " " -> "" jdepend-2.9.1/contrib/fitnesse/0000755000000000000000000000000010236624042015111 5ustar rootrootjdepend-2.9.1/contrib/fitnesse/README0000644000000000000000000000030010236624042015762 0ustar rootrootBob Martin contributed the Module Dependency Fixture (ModuleDependencyFixture.zip) for FitNesse. Details on how to use it are at: http://www.butunclebob.com/ArticleS.UncleBob.JdependFixture jdepend-2.9.1/contrib/fitnesse/ModuleDependencyFixture.zip0000644000000000000000000011537510236624042022444 0ustar rootrootPK ]1 ModuleDependencyFixture/classes/PK|c1W!/lL <ModuleDependencyFixture/classes/ModuleDependenciesTest.classY \,찎#hTaC hPPt9j0f`Xv@l#镫m6m+WM4V6M6=HNn(̛}~=C> )>CCtZ3,I͡a}G}$)~\%O~҇OIiDs=! 9/K,+D_י7MoǷ%}~J#D?LK ~)ѯFJ;~/,w ,3EJ7.?$'[HDyyI$$2$ED$!$E$|Cs1oBBb$HK|@,2y/ IBX%(c8$$8laN"!-;ޠVޔ:k44:VKTa5_nFH?HFN576 kj%|l_}M,S fNO7[hL Sf̢NAZ#}A=5LJ{A4zpۙzLВtj1"%SSuhD~W1uh14]M(Tk -b Sc1-jZ"T=AEӍˆp'-RتZ,k0ϳÌ3 iXuL131^;xx $m(-䵎H Zqβ{6ԠGcfè/1=f66KA}&ߡJAK1{u3)2x ,\5}uFg:%WZ(+kSGWvzͤ} 9QMزd~#3' 7%+/ c(> (F$()k{@9gCQD4z1 AҠ?D ,}QuX5C!UB@Xƈ0M=\mt,lpΌ؜`EILjp#nģZnR+2Ҙ;hN3Tg{6;GZ&ن_hɣyz*Wv+S=2gGX#bW?z*0TVucXct7gE(D,JGt)az)obdʢ(V=>!=T1Bp,*f[a Ӕ8YlW1̅jb UG W{6YlˢRT!f  x#F!¾/Y]H%$JCjKRC3m@|q` u) ұ/:,vm &elq1w[Fq$$\6<#L1Y\!@á@5/z%\: 3}HV%s#wf#]\3JQgW ɳRۖ]~ Ӊ:-h4Oju ‹ɥ+dQv/sl}|( ZFK)"|l<5\RKfALh%b ZQ'zQ +yE,&.x~fYV~lMQqRM 5ӒwPtȢS"MJpƑ$kU޸nVnT:SxjFw~A&Uǃu?YfƵ:ДGK a;:2dQm\ 3Q23;dWyEIW7d#v8M ̰g)q?uۍpjn 4DGKALS ܢ┻h.c|f_3a TGae#:+RUq$=x<[St^:*XFwJ22}Xb'b} TC6mFtcR7[a;a;YTW8b;QSqq\ۣ͆m`U4Da"ʦ >\cp8 _ o~8[tl|O(c\QLp$J+3WϐׯHg(akux.,<}'9S. 6#zo]!X5)MМIv> )?a :/uL*giJd=dDKh@$ zv Ae4͛ -䑒7AJޔEp65` BHtC^e&7^ U"o{E4ܫ}7\m3qߒ5 :ppz*qZܷ9ܧFGbj{P.44~@rTReQJ(V ^gEC2׻'GʠRdaK'"iG,Q+Ju eDߕH6$Q;t:LzA|>tob(3E;\N8iVkW1COFR`z*ZL}D+vh2 t V[=AIkΥl=*@h/ O%mk nfn9(`oI]| Yd%s ] <YlhXDDC }FoDoC? ]*WCvvvdz+FY)6W㷃V5cx8RYE0 _Mme13qq1x`y] !tpC+|FNCN|π:j{'h9j?b6D v:ntZ:tDN}#czWmj9q]NNTiO+JKPimR|aaM[ Vn+P' _uDI '`oK.Oەv욃b@SY,LMPt(yA 7c~T}5.>yt2c( >Յx>PK 18ModuleDependencyFixture/classes/moduleDependencyFixture/PK 1ܙ PModuleDependencyFixture/classes/moduleDependencyFixture/ModuleDependencies.classW xu>wwVZ XI,bX a,d@,d vGjGYrIGi4u+6i+'ulavΣi'8mڴ黡wvvνw~D-Gmt1LR.V0='R'yxsE%ys<_K<|</bJ_ףGx&,;Qn-}/BǶ~?B/,^(BkqRz~¯!L){O,gJWy  _AZDD0J;uN< ʈV^U󰈇갨 Ő'윙˻'Tȍ+7}rdt8<1'\&5I9ڳCHxLfMUհq4k U'V6pBW\ςG"b1GSb'Vp~;5V?j:ؠ6 ⵷,T(jN'3w>E@[颔Rc0}osF'Q{d!cav Vf]+o9~7x_58bS 5suZ>-1@ކM2wK|f};y߆~v\C եmePrv8uo[au4aQԗef4 ؜}F1 V,b;y?]/TQs9>tNf[ A ܙF6Xԁz6yF"mg'9Di o+(YeJ,peN}b9nQzxVELfÇ-8eYTڜ& G,dMcmkơΥ ?ĶTKgjJ|@ZNSՖ G%UJK7㼰s+![L~ ,#q⮑wq9drn^qA:87䈕Ef2;Znt^1 3_abئ8Zn6WגJ+\{Ic= '.oD7QJ]t);uz;NBGtRZaYtXt1%" /?@){b.D.N)~XN"]E.u³ߡbHJ]XXj${ǜ>]E!arvL%q*Ѯ5t.t.:C(n]t.A+baezR?#{e_HXnb2wi3ӝ`*HL_2t8K̄ 1n,.EJk\$/(sHX\ub}XbthkkY^ܡ^U}0 uzdbADZQK #kep!o6zX:nA4Ypwx !aOx>,:/(5Q́zԈ:dto\EߒªLYk|BKls5YyPR仈y ^a>id+`쪡ӱFǘ' 1AuYKB] cBqUѥ25M}"y[́%:ҰLh K8 f'-oipbG7/!m]o2EPϺ8 ._+r6mm=<q-s*.*е/PM2yjfi1/Jh)u0gKl/?) ;(`W3JšnZi mۤ"Zr-ܳg2Xl-xBẃ!Zp0;˔,pnrR+y'+qx\ym[MMjJvN!f.RR'fZuK6 Ո< mn'GB<|L™ WnmRdi)?}J6Hk c6^iPbuWf^N85imԒuZCjҰ@MLӒ4V2^Ű4rWLmJ1ۆlGS@8@{i.e#7f蹢fANw`A5k@=s^7 !@t]8MamR˞$VĤL~['lfd0^ZmтC]h)Rj5#ب=Jo P]EB܄Jڇнڏ:@:E\{e7mh9C"TwP3x?fd6vF(\χx\Ϻ1/H[4QcOBgioh+Vbퟡ5xۑT^䅿\L6L]RK"bitT DTzEc8w;gX`b|3!&hva>. ;6`pex )]:bZ4sNWr`3"OZ҇KJ %Rj EDN|Ax:v!G(X!z|H=㳴@IRzT|6hsɮn$+_Hj$f ֢478~uivjqD4^C @f߿G<+^+O D~0H[~:U@7G?ugҶ?nXD@{ts!O}?zԻ3t}ٛٴy4%7kq֒E+^Э{geɩǧNe$pX™}(}A.ς(ρF9>yyAgБEy t{O)$ٕ8d*8H [/a(eO9D4%p 9y. s{{ߍ+3Hr5sgWfs|\K~‡ ẏiwRFUă 0[7< $>UuֱUef̙oAA3f1RwQ /MnXva2<<ȵLJPt&S3X~PłTl}x?!d,"]U}(I;8O'q"X<ӹ?1C]kq}goR\ DPZ&,WX{QU3#\4m,zx)oa>#`x_CI08w+=0g$`%vwߟ_ffp(ń\[g !:X[_1aRXA(Dž7^OÓΊښ]μmچUmPFW+BmcxnpE1&0#Q-5~HVaj.`2_ PKP1G"FModuleDependencyFixture/classes/moduleDependencyFixture/test/c/x.classO1N@!/*=  Q* D\䜑sgQ!Q< 6JHy08A1FhfnM :~j9+\fZ׶b_pm)yo v氰ojVw^N ɲjj v{"Đp_0E=6ݐFTρ]b"g+PK O1ModuleDependencyFixture/Cycle/PK tk1&ModuleDependencyFixture/Cycle/classes/PK P1(ModuleDependencyFixture/Cycle/classes/a/PKP1{+/ModuleDependencyFixture/Cycle/classes/a/x.class-NA/`?H6̚0vo9I|=å`^]I6!SrFp-;Eh:SIb#dN/nEnyg%lW/E(s1NlQ%%gtYF愱*FНI5FߚB/:3s޴PK tk1(ModuleDependencyFixture/Cycle/classes/b/PKtk12n/ModuleDependencyFixture/Cycle/classes/b/x.class-NP/^ 6moMI-+Qf̜9<_0s;30`<͈''sj`{sY$\/H;ealK4;yRo1?]WLD੪-, +Pwԉ~T<l9t[l؃`[=믍&v'>[|e^IMn?*[徧h@'^6]W|"ZPK w}1/ModuleDependencyFixture/ModuleDependencies/src/PKvT1 zJ4j|lKo5$\ϔ ؊Lc1%B@r l؇gx6;EZ|qrr kPK1݉CmA(3ModuleDependencyFixture/ModuleDependencyFixture.iprZko8>V;1/  Q:JI 5q1-I< Fs{NvbW?OX4F$(VNJ }pxQ깍^FB-J 0t-FEip K(U#)!Ë h8܄sp&v?  ~yQbtK:L{ya3 w< !!3E[Yy\]6lUlѽ{'0,8BR<7^jf2ںxZ[lV}6ޮhOkpGf'K&dB}O E$i oD,?_yD2Gf#6o}mco#(~Kuh` m}l?ŝ,jdv5sۇ`odNb1rnh0ubv 0 0rn. Zz&ļ(iM%}\r;,mt]mtu\]3-]6:K h-$4{R1*FL@o m7) e뗽f/Ωal ISrLfwW ٕI ڞi s\ܚ6ˎ:^K,1^TӳOzBΨ9XMoB$BX>x =V-?6ֺ>5jFS>12u[G$ [ZLvlk=ek^BpYvBV9yR{si)B+tݵ;>?-N/ݶM:f]Rk rLy!kmc N6$#ɒ\ɟ#D BBa(5jY1 9%RUM :$`:N.N(wB\o6u~f> '.*"Ղ#ͽ^nh)=4ʷwe*ڄ\E~JLq )+xwnozf,nu?O+*g|Oi{.;]ZWl/i9!#䖆aZ.% Q:KW[WΈ]|[Gwt֍0ٽktt5Cc[U5+~PKM1}\Kv3ModuleDependencyFixture/ModuleDependencyFixture.iws]YsH~߈Zż:,aF% @cD)l,.!y;**ʫ?^f ێAfl`K#a=\6gu_ben k<.j:  ,W–۰%l2 [?7:W<.UqZs =T)kRth5L|z "]Lu݀az#D=r{^&~tVYbk[mE)7F +W {s- 3~l<nYL23YP0W( D@NĈ޵׹X2A\#Cs*Ҍe(r^1 2cfqDD1g9zwa$9=PX,1c*X7°\j|~uy<3 +w6VW$|/P>mZ<%/]ɥ5\Q{@ISI>4#s Ԧg9"*ocY<,H^*J)LO Qz} K,ݠ%=B"0# 2 #eT gyWa} ޫkӭ<=m1z*w?uI#+\vkjP)l.e80V,6\feS7lh؛@co}$ۨ}g?Z}&u/lbPj!{4g ~0ކQ偾2,STA:zwC-xPmK&q#L=>VM*X΂V}ے4!y˿c[0/*5tGA.vxyH-ީ}>D2"tL-X^g.7U@xu~M-"/2`OyT2\ 1";R$VĎu(h=/+h6y @{,lKu i?9SenERt5V蚸mYdx)Q"X`qMRA Vv7 _#IVkUk$ajkK  $ʮS;C|@+IM'1BnI9Ki˖I4\"kIs!x}U\e'VU5_ΥsyG 1y0g9jiiSQ %9~Vb3w4ųz8)F?w10]9ܖ㷬tD/U̝!1bi0IfKd]!0MtABKQv&ɂ?ػ.H.TsM@6i^⾭թΔdsq^bu6 ʐ9E51ŷ{9k@D1"e.r2rSAG^ ,Hsz{N)4;+g7A&tP9p:q^ kˁX_|Qb5.I~їcٔ09jg!Jq=q>(_Vp2njY r1l׳:TԜ!T>_:+DVjuO75-ʌAʦ)eߚ=Kwߴt:Hd:8;tУ$KyJ#mO` J9>9wO.q^{lL0F9::odP ;Ri$חeLvq@grhPwТ_P/)}HCQ1'QA >k"۴Wr\[?:Z<# aFM2/Ph_dIwO8k**PK ]1ModuleDependencyFixture/src/PK{c1E7ModuleDependencyFixture/src/ModuleDependenciesTest.javaXS8 /u_ǖ2!\@`CfV#d$~+vdvkoK^c.$P]b{Y$3J?Wք! sLଷnH"ؖ3acAX:K A0{Q~DD8IyDIAd)a!AHbA$5Lh~)&]KAus{5>!g_}L C80ק?φwǷopqv{><< F5ku`5]P6G|cVe-I&3$0 &[ PHBNq)+;u|;fG< FQ3VWo? iF-2AQri|ryMO bJ r2\\Q&:!b\}@cAl|xr`1g,r%\3)K\=7`n[;l*׵閫=SN16nf8vOxBDYأPˋe|B[+b8e^D-cUn.)vT8lS H kXͤGܔNh$#L[zdG $uqG:v46- 1hG@pB $~X~e,lig%M`Б&|+T7lطmDUj-;hj6LO@ }Gwvg l oe3)|l nəx:; CJLtİF'uqX0Ӝ5/N$فRc[l2 j9Maߐ GG.ڸ==yi[ؾT/10M`^R =_S.M27'y_Vj-xzώ)rfzZҫg7YI vPo3ַ?Bkts1b寱 {,–߁Mv{Bx{-i ;X7Zp-{).?m'1[s{fį)ab3{mσ~<H/:@(f8[I CK[T(ߐ6ŕT0"ߒ-_LAoP̽~yLv\bJf#x6x<ɖlnIdڅ%p:7E?̾׭2[(,pS"\elaǛddnk/g(fZ(.f_ڡ1=x*=LFubUMAV#7ʈQEn,Ly}'r2uo_PK ]14ModuleDependencyFixture/src/moduleDependencyFixture/PK1TkC|KModuleDependencyFixture/src/moduleDependencyFixture/ModuleDependencies.javaX[o6~/Wp_&@&X , `h,z$ˆ7IN9-n銑}a[֬O$;x ɒJe^&CŶ<NeJrUyIAP.%ݰ{!oR!n-;|^Js%8S=hHzBQ7-y-LJ5-k:Hi:L.{[j#♽ڞ_ 0^-NN``!:zSI$&e>Q% (ܽk eBJ ^Z|TbRܫ pk|@ӟIå՚U\*}̚L}nh{;ҩ3@τZTUqSGDw kIp-m?@Ǫa/IadpE1 AOM12Kv0H\)CE2d9{gˆ+&G \n拃]v,$EL!/a?Hd:ȹ"[mH7q*"Z!Yhq _JqjۧDi;S9h8^6ȅeT5j ^q„KhpXb5{YA:._{LR OvIZn_N /T s=[GԔi5Y]O%_C5"-$Q36I;رU+Z8"&_du,u\|{skdex/͔X5 ךra A7$ƍf@mFk1O6`(,{S<4,A_hӱY#1u]Dc5]7T<˺] A2B$T3W/4ےʠ/Xdd~˫#m3\(al1?#5dHFii`%b"QiMT{&r  LTH+Rp_LyGŸ ?1;o1:xy<`t:}8OrdU~#L dYy! t4Gk|qZ PK 19ModuleDependencyFixture/src/moduleDependencyFixture/test/PK 1;ModuleDependencyFixture/src/moduleDependencyFixture/test/a/PK1 RoAModuleDependencyFixture/src/moduleDependencyFixture/test/a/x.java  XqRCD$P ƸnweUi?BO:k4˵a3mxB@(ݧ($[A7Qd _ PK 1;ModuleDependencyFixture/src/moduleDependencyFixture/test/b/PKࣔ14ɆVtAModuleDependencyFixture/src/moduleDependencyFixture/test/b/x.java 0 { ;dgmXЏTuxO-v:QQI^_k1Mj3nF@b`hkA7p$fO PK 1;ModuleDependencyFixture/src/moduleDependencyFixture/test/c/PK 1?ModuleDependencyFixture/src/moduleDependencyFixture/test/c/one/PKࣔ17XxEModuleDependencyFixture/src/moduleDependencyFixture/test/c/one/x.java ?Iw<51Db'62ٷ 'ω9tmrUK6'@HՊo0R3ێ4|PK 1?ModuleDependencyFixture/src/moduleDependencyFixture/test/c/two/PK 1Z1^DDEModuleDependencyFixture/src/moduleDependencyFixture/test/c/two/x.javapackage moduleDependencyFixture.test.c.two; public class x { } PK 1~2f@@AModuleDependencyFixture/src/moduleDependencyFixture/test/c/x.javapackage moduleDependencyFixture.test.c; public class x { } PK M1ModuleDependencyFixture/PK1~.K *TModuleDependencyFixture/classes/moduleDependencyFixture/ModuleDependenciesTest.classZ xu>G;;ǖ=ll0H%lXƖmIkKbwdK@JB 0pb儶I Ф!$m6m$mHyܙ}h_ۙ;w=?s7 "j'+VzK-:BWrS.7[ zKKc:ӟIgֹLgY+0{Y9q '݀I+aS*PjU@tϒgH_\*]&2yVu$.\:oѹKMp:_!r)]x7_9=r:r f{W>Mt{uާsd*35DR~k5h%V26ҞVSGaʬdоኮl޸Ɍ6GM[t" dƎ&m!fˆK"m{:6ۊ[֎=֬c~L$MtƂiZXH&LmLZk*qD]&3EE yv;5/a: l26MK*چc֠u쭃Lmȭ[SDf{c,:7x{dœpMJ,=IUe m`za.ZvlNDSdwzcV ̂kn_{"[~FD'lNdlQd8aXoETbZHfD,aE15kMm=i+੐VObi@tg+O&^k|e-+LlD7<6嵛ݐ8GR}CK`,@:o.X"~Ď(TS}vb@ow,A@7 U0zҩsB fk RPL\TBc΋i54!X@ :]fjO$$M>d*@=\הK%}S{Ji:Yd(ڮ% g/~ ˥FctZNumŜ.Cv')037׉PSO::`H5] 28AAL_0dN7m1IZ֙T8vIbt4iyJ~㤟-tjO^:G6X>@w3^eW{ĴKzAHZY! ~ԖX>_/\qv1v;ȷ|;#NbZ\O \@>([NKQ*;JKN\LCӸbpo7HŐ2]t& Kw.t9'aDZeZ1fXJ3rŕ6in>ʍPiu'a~cޖ+}R!/زjU 7F ?>1W+J,gv:"%M^sr5-n9(`N舳fSj3klKv]r,Gx jU/T3nmtvأ:LJu!>"ce`6mtP6~451Q ' $ |ײ;!SW_{ay8ȟ632OYOSX`x(ሟJ[pV"i7T(L OsMQO!ν:]#$jn9[QTSh<^tؽXYsDx 9K}(1FxaD >#`Zk*1),>.[EA7 0r Bi# #Pd o+΅G|VBH4i>; eQ4+6l/tE'x@*%XT_;|믫Wg]N!CwN:1jf] =I%z*= 8׏Hv8+' ;UBN|*ghxRKB:-Hƶplo$RMnMR(ԟtvqi;!Xg3Qɵ-t+Lghr$]?SΕ޳QJy<ߕ,qlGp4;t8d%_Ԏ?dR0dG)5N#?0DI4h ݋^QDpØLMo]i 9uU<AWJ \?)|J:;ģ4 zQ=zĈjuU~F@˛]|}γ:w#_̰fvXXh)P*i7M+*=y W '̈y =A}2ba$T 'Gi&M7Jȕ%w]ٍTЃ-H3H {A}yh/vV`!ߩК^O-$.ڻ\J,5G 楝bfs4 )uiZB(/E\4TAKC*y̱Eh@=g?=aX3^Kt=rn̳ngu[].F(%4t-z? iZ˸քaX;B &4D8bۑKȋSGGY4(1 Wq6j"~(u*&A/G{YmZЋV$ǐxM(砠[WBB SXCJmi\ij/t$UVֈi^Ѣ;@O6PA=0#XݏF9rmrq!W%6;\&drMCCKe=OQu3_"ƸL{O弎2Hd 'ïrzqOOPBMC-!|y@|y u}~H ^O@Vx_V!oU_G1!|[yKʭ-O2rjf '|c󑻼7݀l2EƝ=J}fjMZ{3J ꚧJT.xz7zQ#<׏=* L6=7 $<w,ir* Y~.s88r~]nC˩lQwKGP/A{Yyoߜ"[rTaPz 8=9?D~Sa(~=WH߿oT PbIkco 4H! $c+vTR)TtHC^R}.C( kF) wfbw4-bj8cb7b|sF`~& @IIY"NprB|z iIgےT+ kg!ACE:d p X":L، ?Z:&qYXR~ kH ?kux /TxuPg?4qēAEqlO ؑ2v"#T*k1Zp#>q&i o**I R 7c ɉ"4T e\[4p΁\䮻vcF9hs[wXek1G{ʓlɂ f z{4D5=$ ^cy9r[;"Ngs!&ղ8PDۡqI=2S eHRI2UQ$'Tn qi@B u|W)S1S:(hi@,J`@WO=KJ.:\ܿoE'U-O6^6{Cϲ5X5Dڧ@3CHOMlͥhl+9 aɕtuP[ï?OQq}7pqm$擺e#Z=c@՜^>qdJoաҕL̄tH%c3MAXBcB`Qʬ)m_E[lQ^Qu(#rD[x^:FG+ץ/} 3v[JJWW nMT*=J\hLEW%m *[SniBX|)=zz~*l#uD.ȵYE" W|Nu^`gg/>BgINu_Ylmn&,n U&lKR_;cT1~ ;@]'A-mpU:+/p㚗X|b) z;,%UMPbB|DvwX)-O:K6 ̓*PDPyCofdF,Ax8J`wO^+⯞ۭ皜 =Ϊ8t[ΆZSm3 <u=^wp2)uC:c'ǽ*UGoh '>XK%D16ĥ'kXU'e4骅A!ci/J9ẘ߳4Uz98r==*y5NW0m=?YT=Uml$OY\n[v[h$`4𬥤qW?5 ":nu$;'AIYۿQ/qz՘Ai7q:T6 4SP$fhMUTO Dh0)dz봣3.(dD1-6Nk꾶69?{W_~{f]׏Aq*(_,*lBVRaXQ Ӊbo8j%6J/8b9:Z h=EtˠN[`MsY7VBO3[3]>*nh(k(T$J`de=3[T<y3d;d܁$8^FjY"ۂ\lQڧrSUuIH#̕(kaxMpW/a_qj -E^<Lu悙|pj-c>E[2P/ iCq2v֩PK ]1 AModuleDependencyFixture/classes/PK|c1W!/lL < >ModuleDependencyFixture/classes/ModuleDependenciesTest.classPK 18A ModuleDependencyFixture/classes/moduleDependencyFixture/PK 1ܙ P :ModuleDependencyFixture/classes/moduleDependencyFixture/ModuleDependencies.classPKP1ۀtS ModuleDependencyFixture/classes/moduleDependencyFixture/ModuleDependencyPaths.classPK ࣔ1=AModuleDependencyFixture/classes/moduleDependencyFixture/test/PK P1?A ModuleDependencyFixture/classes/moduleDependencyFixture/test/a/PKP1CSF r ModuleDependencyFixture/classes/moduleDependencyFixture/test/a/x.classPK P1?A!ModuleDependencyFixture/classes/moduleDependencyFixture/test/b/PKP1&.XF "ModuleDependencyFixture/classes/moduleDependencyFixture/test/b/x.classPK P1?A\#ModuleDependencyFixture/classes/moduleDependencyFixture/test/c/PK P1CA#ModuleDependencyFixture/classes/moduleDependencyFixture/test/c/one/PKP1rBzC`J $ModuleDependencyFixture/classes/moduleDependencyFixture/test/c/one/x.classPK P1CAh%ModuleDependencyFixture/classes/moduleDependencyFixture/test/c/two/PKP1"*J %ModuleDependencyFixture/classes/moduleDependencyFixture/test/c/two/x.classPKP1G"F 'ModuleDependencyFixture/classes/moduleDependencyFixture/test/c/x.classPK O1AE(ModuleDependencyFixture/Cycle/PK tk1&A(ModuleDependencyFixture/Cycle/classes/PK P1(A(ModuleDependencyFixture/Cycle/classes/a/PKP1{+/ )ModuleDependencyFixture/Cycle/classes/a/x.classPK tk1(A*ModuleDependencyFixture/Cycle/classes/b/PKtk12n/ ]*ModuleDependencyFixture/Cycle/classes/b/x.classPK1;e?' s+ModuleDependencyFixture/Cycle/Cycle.imlPK hk1"A,ModuleDependencyFixture/Cycle/src/PK 51$A-ModuleDependencyFixture/Cycle/src/a/PK O1`55* V-ModuleDependencyFixture/Cycle/src/a/x.javaPK 91$A-ModuleDependencyFixture/Cycle/src/b/PKtk1U<G* .ModuleDependencyFixture/Cycle/src/b/x.javaPK s1(A.ModuleDependencyFixture/DependencyTests/PKb1ԡaC 3 .ModuleDependencyFixture/DependencyTests/content.txtPKb1 ?6 s0ModuleDependencyFixture/DependencyTests/properties.xmlPK }1+A{1ModuleDependencyFixture/ModuleDependencies/PK}1\(w7A 1ModuleDependencyFixture/ModuleDependencies/ModuleDependencies.imlPK w}1/A3ModuleDependencyFixture/ModuleDependencies/src/PKvT1 jdepend.dot $GRAPHVIZ_PATH/dot -Tpng jdepend.dot -o jdepend-report.png #$GRAPHVIZ_PATH/dot -Tsvg jdepend.dot -o jdepend-report.svg jdepend-2.9.1/lib/0000755000000000000000000000000010236624042012377 5ustar rootrootjdepend-2.9.1/lib/jdepend-2.9.1.jar0000644000000000000000000016111510236624042015160 0ustar rootrootPK /R2 META-INF/PK .R2]E[gMETA-INF/MANIFEST.MFMLK-. K-*ϳR03rCq,HLHU%yRKRSt*AMtM 4 rRs JKRt<4yxPK /R2jdepend/PK /R2jdepend/framework/PK /R2jdepend/swingui/PK /R2jdepend/textui/PK /R2jdepend/xmlui/PK .R2p &jdepend/framework/AbstractParser.classUmsU~n&%}o(%h"QZ}VKlKؐl2/Ag9/Wl^2/{rss7.{ ᖁnY'bXJڭ(:5+csp[|V@wtH-ד9#]O`"W~ ߮dW\z~[=+tfs墬K}ZUc}ݳ B]X=- 0qvlY ?jE)0Ө{W Vrmu&>5WZO]@MOd [^.T 5^icԓAqڵSo+|mƭU,c ]s<{#5'(Ql Q-0-*a5E0VaO(I3 ~{G u2Eo8[)e)zUz@ٗ pZ-* ;>U8̙9x44:L➉p{ db oxu<05p/pN;J˲ෘ)mGf<_-0o F),oG>K -B?UImOHzl~],ZWs5_ (9&*T'iyHqG<\A"WQX`™ qDZfPxpi3$rTfrv4 . Xe22" {Dg9ۅg \;Ho>k#V(3+5*qk <78? }ԟ/;!$fB F 0źC!R{J})卮L46CPXf%zź(#:bcZb%_`aF{EXQ\Mqd~xq|ܞ=P ((퍠PK /R2\5jdepend/framework/ClassFileParser$AttributeInfo.classn@u|HiKi9Z'H5\q "R)(7$ԩFS[B3Ђ *Xgu76ȭuj+XqWee71iO&<.ڬ&pyNqvA*h2W+wM?+ĦgRXU2!:::~sʃ%;qqv:zMTdj9. CM ϯX8|^.P k\VtJXFPn~z0O5(ʢޯ?ɼDK1S>pe4MWqrS:j5X~a,2:nLYm#J JM &SMܚ%bEI_D`|mܙ!bE^p״+X6G:PK /R20q80jdepend/framework/ClassFileParser$Constant.classTKoUď0u[ M)7q 8Pj0i iJy4LIGI? ~KEJ]`  l $@33Δƒ9<6Qa7NxyFCJ,r&Uՠ,KI "_׊h/2.s*&D*|xqEڌm^bp/3ڊETkffڋsK֜{O!Õykٲ G{\)FLfMNrn-:Ǯ'v=E[*99x5gξkYjCm)͍ZA_[+߫?q0;% u]>2 MČ&@ 'DҠ6=H07HѷHwGw0HwDDa"0lXt&R6>nD8!F#}@HHsH磑N#pVnt8Lq?q73܂z1ZV)2z ی-loao.n!CHƇltAv6Hϧ>Dz%~Fa?gOL_Bá>!jx'תi<;?ˋPK /R2;rɷ9jdepend/framework/ClassFileParser$FieldOrMethodInfo.classUnUYĹ4MpvB/)4m:][ 4?HZUHq*̬: Xiϙ33̙of9P19^r. >lx_Tx+a,P [>bM)VTa5!|,![^k ndѪC2l4*lDA`UMiUU_5źN̺-iw,gS:Ae: !b1uSبHhɴ iuJ Cm]o'0dze^fR hYvHr9+$D^b,Y\)bTIge-FaQvlӪ &S-K=_׭Z8;MOÕl:fb&.mWnrc6$N!0 q05ŤcLaR`;T&8=T<9a h8,KTB<[>m yl Ytgr wh*]+?5|sϔc?Ɩ4tݱAYԛE Kzu&2Q(s<'8ax9& NэknH# 4@x  q:I7ŚD: %= _zz_H3! bPbDQe D[HY&9YJѫR^+eB{<H?^ +Q7q%9 '<9Op<eu@ep!O~Cv,p)"1tZY~Jtjc[=w;7<Ȳoa:cv>;x^ζ1!t{:0@ơ* +'PUQ2V{(xH)Ge6fݶ70G#qm.g*zR^.ᄫ4W) PK /R2L5'jdepend/framework/ClassFileParser.classZ\o @` 220"#\$wZ{glZѸhU]v{{bȳShZ.MerRHO@)oi6IsOt,MQ49"?!}hfpL&2:ǃq'<ټ4wr,iΖsҜ#͹Ҝ'\ ͅ\$\"ͥ2!ϗSd |&U~ZFdtn~I7?A(w6? ~S`%` P+/K{}|L~_Ƀ~~X'<"=O~AnXF#\'~~Rz<烲"|b 7fKҼWU~~o~~ w@n&?J<8.q?O,} Ao)M&_nǿaPH F6%ўkCx8Δ w6}n6'BS`MӚkV52q#%և2omii8m]GbR-u-d4^ohjUtSk*Y0MZ׭lҐNM5snhk4aӞko խz945 綆~&SR\_RѹVceiumk;ZZk֦@bQ#5+mM5O? f4m m Ujw)SF<01>4` ZDPyO8@$^9 uA漁ɻEa*jG+{a{l5qam,TqlXg'U׽=~xj<U@m3K3 R(4AXe](j %ph,$V0JJ3kc`H42usx#_ *_Zt'"OG /.P0BKOLG|q&`8= Ub*o/-Y"1ʳ/5 $"jTYHgjyPSټ1ޭHtuk$\-8͕f( gm.ݲҮkiPYRmev#5NCl% 71tuq? NefxcM@v&1)[R:G;p+R(3IڰED+dxmlHX6Xa9` cx`d x;LX\İ܊kJ%#JOrv~t%B@l%S~|츀Io 7EXYf$Ӣq0//dDq Mhof*FEP?vr- GZyiym6&bK,Ӹu 6K_0!X8 ;buЙ3ֽ^g-H&t:L;䱳 ?giWL "fpM̏qIL\D$tTx9]9ӣ{kHҁ1hҡW;;4ثSgϟ?_8jvYYe& HI @tcC]a3p玂2O. OI3 !'BF!AF?nAߤomz)8~34-z>s}1]zAߥ[vu!*lr ?oL)ݠ4 hQc>7]Sb)`$d ruqȪ?k  >1BC^ Y|-.ȵ䶮F_MI9B}]g )gKu3Hfr3e?P4Sj&T64A<) % Vٓ8)VFAņP*2e0F ciPq21NM3 G* JU&\CA`75iFc7oC(XǕb@Sӄ jsh| Bt48:dG X8T,qSPEjO!p5PG ucVT !m3T b3\$Q]5̈́b ՘:1* Soj 3,e@E$w U}PTO7P5q:SJs(Geb+|j@Z)!Aӕ~9!y7KP4b^K(ƕQ|옏`c$O901?? =/9_U!׬VDMtD(:t BZ=#F?o B#̪Ʌ2ru{Nr S0q lSq}4b_>Ns?[)~^ T{y=xH.( Jm4"g"k~j)vZHpdn&Ht ubfs~C^!F-Dxd3KGtc̓m"b=3#8@sƒTr4e+ДW*DH#4Oƕ"OEH/_$wL0LU@hMF}TD[i?8*(M;CCHD .M!:tEHsh"OgMy64 C(L-ՈbM4{-c,8@::$#P~A' Rvs*̳pawXX,M `:!cܐnH(-H{m&e0f=$2_V./nY޻#G`\ ѭx6@S.In/Pa>_<!_o 6 L?-̔uq?>#u pZDm2t.۵ [f+(9%Ɵ1L+lqX;t)5C#ЀGF`O6d?"B^G[DzȕFIbM>IR`jWx:z ]n;8{Ah1Z[OCsai/jjMLljZأHuLצ\ܓGѠU6w`*^:BkXͷ*r:V>xIY޲͡f㬵*}0q-o[X ·՛P޷`o~ j`m-"Bc/PcBMΰ ^g8ӊ3&A[EH5A #6EMEL;;@;W{\U<4= Dܓ/#W98R #?hrAY\!X 140>g.EMk <unx6.v>OvοҹesڍcpOZ˧qmś;ll/h^``5hr "а Ab8K0箇L1fb:Lf╜m1R31'[L|gqsM&4 G$ƜGwgw;@;HFi/=focNsutZQ~֍zl]::y:ͭkkbn5'6Y[iB'k3D„(7[DYJkL{wU>s(ZB70*Nq!E*Ϥ>Y!I-Sh:ɅZ{=zo>G\Rlp珒j9[?ުPVg0]LrQ+>Ik_.)/ p/9np-D@ZBY3s#K:-Lع9"ĵP˹\/S=]doTݎR(Ũ]֋n{ѽʓƬ/sz7ᓸ=7Lw*`R :kk,ui^Mp#]s7qfT\M \Xx2FcAGh㿄2K{mWk[/uJ m%] jΰpEj i2,{zf[Rs>2V!JyN8EvN6fsοmrM?,*Lqdg6Bޜ}A)̅* ⩮ss(炷;6_[|ATť;g[^` NL()DGt1P&+(-QZ`T6J xew3^ilB qKEcv$zʹ zHȏdCqONeeUfRl֥$aʀw6Ak2(s Y\o#+w-l 9 @ jyRC|+.v;iKځb ttΎSE$Fbm^$P {(Hp_**W(Z\U#3-.j N޽4,ki}y*Lrv^HѸ)!2PaaAR҆AIZOQ=?C'Aڌ>~n*Д@Qpw-g^/Ӽ )<E<L0r 4%Dg eIe9I^^h& g.K0K)cʬH$@#6O;n<(|>f߲4LeQ~C7Gs"[ür4l,u<- ۣ!hW3 b'@̹F&k똚˟v| n`Ӆ8 *x3tp+sؑnTB:RI%j#USZmթQY*D`"{U*BQ[PQ[y SwAD:}v~FCj'x|R*:OՅz6wuYO0#Jkt=z8>!5Hs-.%ʟL1<` ը ^n<ygZ-zϭH(ʂDݶRq:L^IGePK /R2y& ,jdepend/framework/DependencyConstraint.classUKOW6M4Mq< '$$@HpHmڱ=3vqZtMU%.ԀhݴRW+m;3  {;yp ~Q+؇!]^ 3"vFƄ)ĭ"Հۘ⎸qWI!xS}K=û> j:$ϩDsjivD-K <'6 'YMBnhVLwچ57uv6esV\V+hF61]TG%kC32ɼQ2n!;j$͢nF#]48Fy,Ⴌ\;\-JsS+rZyU33+!n3C[0eJFz&:* ZQ5Eh iͰ:b"1l_B1j]i,E _{WJ,ZQ3LzS]BSޜՊg kmuř<_.fA]qZTp]Zw8 ϥ$\dETi3UcN}0 QRLpZA?*8/ĀeᡸHh KgǞM֐{,17L&\Yfᐥ܎Pʌt뻌PD %=z׆Vm2!3P-3]1hm;wcV-ZsKSlc$'+x#]ۗx~~;$~`ꩳ)@-5%)5k}G6D 8d@3zq+žq}=?¾;*<;Oᝌ7.Sy >w}98B{!")@zQ6ktIV5Np$-N  r qZu*M^k"=unz!BkA7ioI,a$ K8BUh7xgHP^C2<+J Ú7qۄ` #ʹZ/{IURi/q&c/'x"RtS8igTؿQKlϮ g|:3*|Jz3Z5r'@$[C+=Kɏ!W`0+0.FYXs0λq*F\bMVwDZ;;ih}rPv%4MzU]flш82%?u|1|[̊@ _U);Yד.K.(w _vKMߐݷdLvma.IPK /R2a #jdepend/framework/FileManager.classUiwe~&i:PHhX ,mQl]d 4!) **"(/|s=9'? 3$ }?.vBN|8QV p~$IbA*FCp"SҜ Zl[4aI "/윕4|4/\WyUU^&eYy#+A[:iZF"L#~Vϛ鎝1s z"a2L빜+G3Me@ڙM jž7~zذi{ ==[E5?jgyɤ1fd)K?mZ:iW#Ez+ 4=J>O͎ⴞ8f[HHBd\ڌ OlB۲`~-t_M[58Rg)0snrNkD61e,jn)l:MTH`AfWްtƭʔs:Z™,kJ+̾. {5p9=! pD J3 $RW5k3K Ӱ - Cn W2d?KA.?|E1sEw>AI;1PZ>Xr kA;ZM#FީyfTdesbjfD!RnҢB ?JQ=ԕwLORG`+eOd3yCm\(R6ls4|Y(;Ԙz ?Ǟ`*FlB,"lƓxB.6C ٫ !X2D, l UP|Pc_5P9 N@ssgPf1ׂ(ըB3=iJıE hK\YvrUJ5,;nhaQiߎ"W p\0"S3-`ε5G3Y{ao}^VNa>3Xt]x,Y:^O08 C#7@ʣ^P'ץ>RxuSH,=,lE~Z-+ $m=$3m ( ~/F{,I~q XS6MT$<,eؚ]MA&W/N*_kWӟĔ UNB[gb9omPkն7Zu,Vn-IJp!gLLM8鼟`Gy&%,`]~#YɢJZwI/=uSgbi VeNΎE8^ģPChBk z07Ϣ4Y%K R!2H2Ht,R G ]:'Yj[T:1aV}?PK /R2' 2jdepend/framework/JDepend.classWi`TWn2I& Eh4$@A HIU_&00̤3/@RVŭuj6JL؊hZ[k-; /?{w9o;+P8&D=3H  CA؋pwGhe, EA9D}2_fJ >QOS8C8plCF jq\ㄨ>"8)__ _ <%OWe A+b|Soe2(32H^<)~PgFѴBEso⍛voBiO,m7I)m&{RdjoƬD"-ZDTZk=f:-ʷh!cn!%3WR<$%фUܯ9G#V,kbVnQ9U(k%mfW;mɈ4S1Y;>kwgyj;0H2UO%)kYL+}BdFݢnb r^Lo-%S umjb^ җ "qyo #>1g Q9'%n< Җv ֲ-7 U8wkM$1]CuZ[\+e^W9!ZI'rTuALf,3H7Dq{xCeh"2nZ aR }JѪZckoxT@jhBi7A%Ƅt DmHa^rJ6gY;DS)T}Y}u7qr B%dFnyQ$r'  &k{e1: eE)b*yBCslEBTDrpJbq xy\k6\0N`J\Ex/X \\ [ɕW w&Ġ$W0xq& Fϰ Ң0gR)s@n`2zYϊ?@h 8(0 4p#hx1p73s 0qoB\l?9YNfC)Yނ[ U "oBGxU$V'mf,غ -^ %,b9$c"S-X;W1a9]*ƵڜnZ~.twaZ]n{B<ۓfUѫYȊJ͈?xmX^;u_:&#ƵHjP>NX o٬Q f:[ɱt-sG=ήKt/KnA}ĺ)/M*FdfRA͂'Fq?[ȏ)ҜH#V,zd# iw˹ZB#tj FPg#pJ.e sE gPD~* N(aLlg'P:)Øzhg0-J2"( 3akzl tF y ˁ,3qT Vtqko h GB{qT8gNb >%G]p܄bVuQjt!=)t3*,iN@4q ]97? w]Zq-ޮMe1}𷗊=G?_4.?èpqM4G]v I>~\4 m0đK\hK?VY؇v<mܝge(x |).Lq\t0gʆȯɡsKg C3ᓨq:1(RMPr z<OsՐ{rq'=3AG GF@J 5Q{phLaDsx 3g]fag\qvaiiø|,G "|3Z<Lfy:ބ7ku܀=A C,NKr^ZRTe0]C~UrD*\e`*)? ] zpE@>wSZt)a|?;'I҆ V_G2X6}"5Z* kt4Ynl'imcj |9RU1!thlttT 0E-ŨQ\34J!c j]u۝Nivb8[#kzC-EZjy9]GciөwiݸtZw4J:2aMNRNw6gnw(\)>h3y}(L[OM(S͘ZrW+V _g pަv&o"t4pW}:0̎*O*L_64db|M(RW2Wat 5XImCM;4MDD\ttwĻޥ2¿:rޫ)Rú>:Q5PK .R2-dS1jdepend/framework/JavaClass$ClassComparator.classRMo@}81qMZiKBNKk8%RP"l%88vqʟ¥Hg~ىHzyۙCxشqA[ᾍ6m<_qzW`5,Xw&6ǪYn'ʄY>#s8񸙌NQibn+iMA{':鯉U*\n xîRG*zCyʆ+ghd(@ TWظx]<`{ .O/XͩIFE=ix K&2{D7[F8FKtX%SnbQp ˳fCuSK up۹_E{?0| VjX)^maU5,K̪PK .R2R!jdepend/framework/JavaClass.classURV]2Ʋa!)1\iPZb - [1!9|K yhg3t~T+ ùlZ{s`/42>1CE} Iaya 4T!l*e]XQO F+jUæ)l)Hj84dlN{XTpiuѬn@y@3x7[v0 Zn۫ĒXAŽxŭoj9fp {,q"Lun6M^~[;(3H qGRW[6>&(i>n #S68~MVƬd:NڶY-!d֨C .?"-5KpW0/iK0_ j>Y- ?`XnN$nj{X:氭LuѶ}1#)cI4f9pܷYeOuQQBAŎpG3ίIuJr%z WYYK+2u((F\gL "H"0R$D02cnAf$-Lv$$? Nvp./>ًςњ.u; 2"ٱ4krir-YEw!+srSFeyouޡGdWe߶$<3K!5|$a [9.SA PK /R2*jdepend/framework/JavaClassBuilder$1.classR]KA=jY}هTA!AN5Z!~@?*IV=sϝwXaa60f#y  MSj:Ľoc~]6aHTp-٠]dǰ6Hq!v5C*8BKH5{ε4qs `HW: ЯEvm}R&wTT-xkO#}RutCIc5~B!!$}Z S1~~y#85j\wj+|KuE f[}m'Bo iob3"O!gqdhfa㡊d@G+zC"{AGkILQ>?C Jw/ PK /R2@o(jdepend/framework/JavaClassBuilder.classW_w~vw!4km dKRiswIZPB5,ͲIHk[SxxT5YhSò=>;[}u KKjBFa8!";!pY DWeg.kxJU|LgUh^7 *လ% UZ_Ǽ PM -Q}GwqSf ;o )sNlcƼ/;tκ2GRVLYcZTTQ\| jNL q+kf&M1c2Ýx.id%ko\ U2l\6Ne|dLڣ[D#Ԥf&!Öw3R:Y MVeZiWpLߩ\&c&+e~WXA[c3Z+GLKVoդ9UG"T,"k) Cpr-?^w`B.kJ v tzu[ 4-8m3Wӆ]ʥ"nҪ%|!%)WR+A}M6M& U .(N*ԯY}فcI&'W@0#`h4K5op){7hȩ(wާb,hAP6k}ﳺAU@1` 'lۘ[yGǏcDłg:~_e%t1/㗫V]ůt'4cdxOVvd!S4U-qKEQ~c6!dw:~u:c:(ZUI%^PpX+月ldH[ޭ9;KD?IG%4Vo .\ZMDxK?ORpg&$]SzYS`mk"Q2$@ߺ~UXe\4#64uMF* 7Nd2lU+&*;&{iەe|X+1+(7h][%BINNY[# ++x[*CdyE4IaylؓW٣fdw2nV:h㵼 {%1/e0Uwp.=vlR&́9K4޲d} ȕvhQ" ucŽ*@ {/{;cSege~NsjVPˇo W\5>FA :\s'=sUs]U K;]C-%aϐN1F5y39NZ>: 6kF~G5)7@(Lp>Aeꋝԍӕ_AhL!]>ҳzkSfb=Β%s??znas*0y[y1k?+F⽈{]A{ q @HWgOhcWѶ0uxo;þ"vY",}k'^ {)^9 $`aQrgt3o<愗v#IQnQ1EEUDdJb{ɔwUB/#_w'_ʋyI&:y1¡gq㫸Pn'K,C! t%h,QJ<;G1'o8u&ǓԘ쓄O NbI\f8f{ihg`pIniZv{VaΥh[]`/x|yK0^alpN,!{J%_ ? <ع>{r(YxEz?Fc~af$U5fx{X=G$ԼN^(c4H:~("CDsʭT A""X-%E04%ۀPK .R2V:#jdepend/framework/JavaPackage.classV[pgV%gԱsKȒ :qqL&)+imˑ%GZ;MZhK{I@Ý`B :fx ^ 0-Zd0;9;f:^ٌ,υ𐎚.-,ϊxx\ \ dOr|\%CxVG+(g_ex/KD,q__ 5 9iih0gs^ L6mکt>A;!Hװ?;e*stYT^[T&eYe0Xӓq+wҌlL2s)Y;{d&Θc1 Y9Q:*t|n i3v,(yĆLI4l,Ë:Wt0.hذ&k,`])#8l)촄uo@m,mٝs٠Ow0 q܇C=YEPWǃp;6~AǡXt>̡Nf >g4.& ;ѤQ~Ρ&0F oK8 Dy7w4E< aw+Q⹍GՏ[;-l l .17PJ v9wc=>hH4~vV2AId1q4z#{ Ԑ ӕu0#:]:N0I򽴠CѪ=쾆]Zu~{{)R} Y`i,Vzi3l e='h?R1u:X|ԹyZ>ˢz"x4KꈓpYo72_j*:M~~q&FG\c&7.`e1l=e; yA%Ml?S]8:ݎO9NZrze-V-Oa:un`3O4OO3 a/ eHx$$$`V%!\I朗_p% ?.Cn[=+"nPU-ZsU XID;eblKWX5s-|hohq-z:*BۮG2gO=[\4t Ǎџ!rhV(-?hk lgORGEcd, |i~Z봠;_~|U+YL)g4w塣"^VPK /R27[)jdepend/framework/PackageComparator.classRn@=8q )'RRRQZqL4#>>\R♏B̮BI̙3gf_c; 4dQ޲{q*X5 <`XwZ鷬>9DGL|+.Կt97N-WAi@ [̬ :8KyYciҎc$Dbeܢ0JAT[ _H$BMo efk#~'{pTТ^O#Ui/T3JRCX@:{',yD]ue" Mub _AIa+)d.m$CX,>kdDV g@铗%F4n NPq(q>g(bTNrW?9Vgt8[3Gz8V0FgI'FC!ibeVJ1BJ'jmd 9 #"a! }^,^.bE^ _PK .R2}ő&jdepend/framework/ParserListener.class;o>=NvvvFĢIJDbF ԂԼl}f#Wp~iQr[fN*#0؄"Լ",R)fcdIKOJM.acd`d`bFFfH21PK /R2ꊸT,jdepend/framework/PropertyConfigurator.classV [= B+5e&N'Ů]!bl.] bV&ĩy 8}%mGkzfvfg93w6KSpT$TP>c^CR]*Ѡ#_)óxN>Wm"g^Pb/iU|,:+U=r=hn}44⪊.]W#!Di?\B/5 V 9ǞkqhOf}07~HA3ўhpfAܰ&OiMxKm%\rPDxc̊mg"E s2(ؖ%WtrkQPxVA&[%c6BrcF S&mlsl ֑A{+sϛv{ kTN ]W8b|Ј2x\\Ӷ `9ÝRPpȳ{؞yIH3" 4 Z!nmd83[M(sU.sO]%/Cr8b&츘0q7WYWqS#:=sAsҲ3 P@A`T$%gc%]FW$^6V(ط~v{5}<D MBu(I v۞s1r[х:F%ًqpXb$5N1RQ3~:7&>2::ANmYJEcYbݕ-+:?Qk:ޓS6ȗ+*^~r?39fqaX: 7Ʉpڤ.UMCVYUH:t|d7Z+~ pMƦYJXtIQ:a;^XD"墪MQ]H~nII6e$xbVX.Q,1)e<"ƛqLYs c+o ֩ C nwRHTR^昳kZYu}$x*i 2s3 w/ vnJY̶\ô墏eΉ6ܧ\sC"DV썛hC ȋ@ތ%{bq;!py:QW83",@QЄF-ִDwPRN^XܹCXHw3cvMЖPأX\i}0T+G%6J(k 0N5NrMkUTD%vDJؾ]t#4>lbG-~ŏo5} 1)LJ騣-LA,q,h=B 2s]|;B?1Ox9]x2s7QK؎nGwVCҼ#+,ao-a_6<D+H;Bu% Kw&؁'='k9\ȹϸy՜Fݪԏ,a1ƥ1u~#IElOnY %qyHXFé44y(o ͝ `LJ"07j*tmp}&|ᇖ鑷p`AN㑾jnIMT/&#pH^G UN?%$JFA(#Un=S%!j3 Oq0Ogr1LwX׉tz}x׉"׾t^%5"8^c^"_K1<|{K`Q$Ϲœ~() leVY;Pm=/['\Օ ghLU`{I?PK /R2Au#jdepend/swingui/AboutDialog$1.class}QJ@&nպBgE,UA(^=OIIKp>%3A,|3_p1,,XƊU|ږ>j>?Kuו~uSpҶHeDGRڽaQ &RCS׼2݈Z<h: `.q=I"Y >Eƒ_n}O}*o LM5F,{u8PdU<!ƺ23{RywR3f+& v N UmM4;_\ڏq+o` ǣ1O`EXǔqq}fuBf9g^1|[CnίY,`Ҩ9PK /R2N#jdepend/swingui/AboutDialog$2.class}J@iicRZ(. i2)Dc .CgƢ^H3s|9;U,D9L´L*k 3f n ^F[z;$CAOЦTRo1RsnRM*qnE|!eksKs$sJx7I"(3֨NK2R'"!w{^{N(ؒ}[sZN1Q;Ł44]5X.E8;/bedSBq)|m,d !dN38LnDL߹&MkXdh1ӥh6S}<#hkzi7,p>G;\`oM! w4U2/*6IZ#3e1`){|PK /R2 !jdepend/swingui/AboutDialog.classVsf)-[(9BsG19Hp‘M:mQH^^>}vCzә0}з}]q 1~_Ёdtbԏs2< L0&ÇqOb%%<%CƋZKHɨgZLHxFFi ~26b~dccf:6ok3zWyb SIȐ$Zf. Eg hOYLXwšs -cwVufU,%NFk*6E)L U2Q E\(-3[DF3KuɌ{2l3+h9evt186w՛q](RF2Cpƴ;n-]aBy oRzOyĚz=lU)8|QU\S^Wޤ2CXvJB ޒp]xGxXc(vivoFf,x_*zl{W.֥J}Ex{M@mٹQ#*ː1({Z3Ge  jY.H.tмQBT^(8$ nSm^}&`}aO:|/W_bXWLf o| Mpo3+K+rQ3Fڑ LYr.;C%R[ڎnӘzl\3MR+L-M!]"2xL$^bF-`)+7)C/Q;-MUJr+IW.w3I8]!O%q T5jBwIǰ̵xEכћ/= 3gI:AOFzOf&'- +ʫUp}9@N <<'Q[ol R~Q4VyL]º<jI_7)< /apcMbCp Myl.jIsHl]Ama[M:_n+$5غm*K؞G(RV$jUѷ{UQZ}_"+ip\H;/BECDml% ^l:lASp{q8" +ݿNHZ6q /t8d 't_8 p[GEy y;pxomYݺ}Qq&hh"bLGW2h L4fqZbb',j,.fH:0aʃSP62z?[ 'qPK /R2z"jdepend/swingui/AfferentNode.classmOPwu 2ǂTx_2.v: ~*|3I|k2uAnI{Ϲ;s?~0*1`JE q_\edU(NbFgT9#y ê?,2wfD80Z#ķ"_6=똟ޑdCah3QޢT9Zy1ܠCF ̹ pYnz*rJfK uۭzJ.v_֬TkHaY[57@F;+9V4⅂5 Iի70 &-#=u,丑n9ˑ~ƌVk3NXea6ꭣ9a)Cc_<4/*>z⦟HE|A 4c󟉨1EOL^z6J&;}1ܦ_ AJЏ Ajäc!5YR^ +mg9DM^UjD#U:GoU0&d2y{YO|s$S5Af2;EgPwSX*PK /R2M1+x: jdepend/swingui/DependTree.classVwUM&II e&R7DA(TI NtJ:S&PЪ#Ǟ7C˝y/*U\#1/jP0!ˬxIx25 QHd2B0Q`20Vak脣b9\QPҰ g1gīxMuxCA ͘2̫ҼeҧGii'/ vSy1#ϟ2,BYVO+-fDž;ji'f898f&o*)\i!\X&!J =:jzDEγ۰J/̦^QV:ĺ5sfqV LvAINo̳xHS$B jdjI;sIabPk'N |QىET'_BqfݜsKg5=(!Yщ RCg'\sZ;iB6s`rɛL0yT[XPw[::>: NV7/\üz:>:N4C:>:͗ VLA|YV/񕊯u|dV2;VRuhб=22Nվ~nIql1r޻6%G?AIl5&v"e2ayiߣ 9J4j+?h<ǽF "_)ˎŸLת0͵{QjT;˘6%ƗlW7Rfql '5z+)]wDhگg&QSņļ!|5,Tj9mU&)yJVLFtK='M;_t5/2cr:%)8f,yQȚ?Kt'y Eo>&iA0L"5Е\]DCVYDc6TAs*P+*'ʏۢ]x<2I2yNVN;2Zx!{lel"X&k+}T7T{ф}!h7Kqp$l~o"0̡ӄ \$$SwΧ $2:\qz3\7MZ6Ň *?/FF.c_PT7H@M 7VSHs<8fv[} 3SQQG(p9rg&p.m2SZΒV3 Yӱ; 7,z"jdepend/swingui/EfferentNode.classT]OP~(ḱ|6`_(2 JDE(vi;x3Ie|OU.ܒs}?|0 ("Z%!").MsiF@JDøY~sW=a<!Ȱ ZI3 )X7e=BEm*h垭iǖ}P߫5||!! CWN7ѮfTw DrV^5U[2{{,00>A0$Z!KITfr J_!3"I]He,nt'q7km69fI ,Z"t^ŝh 2 5ꂄǘ $,bISb-\f\(U2iN)W5GV$d"akIXGk\X\ML0 65)C0 a=hZ_QY;x q"ijJ/%%ÔreWX*qsN>CSmCNw\EM/?RVJ.0FߋEHN}&1ZG\t  0L F0Z]Njh́S9YM\`}Vg}V‰ ^LyRS5״dI'>WJz Fi*݊F(yT45/#Hr/1~"b*訠3E OgHWMrغPOhCPK /R28jdepend/swingui/JDepend$1.class}RNA=;-7 "{I| ƒɒ0Llgk"运 ?X3:]us` m.kేzx5cXwC%9Sq}a;R\a0NL&*]Uǰ(h@2LuO}}8aOD96;Zh?q, Y)*RETm8N>GmQ9G.^pD^Xa0CC$&S  812&I5_3?<Èވ&]*zcea*[it=pI*Y0D!t# ^XK3EB1.dQerNyz˸ޢl3[W(F9?8xpGYÒ,-'/%<mIPK /R2jdepend/swingui/JDepend$2.class}Rn@=넚CpkI qZ(T*⁠JRYuK _ G!fm $גggΎϜ?~haÀpCe6Q]PQd0[ـ``]B D sT KH 9G"7)#J-3[0;ވ{/Po%l86HdWJw\rV$[Srf&X@D&LqtX&X5C<ұn122+NrlNRO'Hʤ$۶hmz =;Kpk{>}b"ܡ=M)#, XU6NM?ar)\P>嚦B%M=)$\ ACI POI8] "y;,65ˇ}/D=.$+OȿrJh6B|gRHO#=)[B#>̄2a9+XSu_PK /R2NXjdepend/swingui/JDepend$3.classTmS@~[ uZ%-EDyQ(*ecHA?帗DL}v/?} (A!ŵ Lr1%"#!%i>>b&'r)w&bNļ]n'ˬƌr:ҍ]GOW`İka^7t{Q@Ti#%#[-3`k637 YBVTSsi9gVTbd4 v1H*<=٪c!T@eI*USc:'(}*cdDXĢx!c "2VR*^x-#7 }jKIĖfQ-j#+d51SILKd(6M3׈4'0m8P j{Elvj\gdZcϞoc{UgN(/ٞ![=U ƋQ\r{ 4?!;W|"ƛ+z\cѯ,] y{l[kErJIybO{7H_61B[-Ҝ[9>>]|AdmBy➏ ). utzZWXwߟC u!G %•^R@Q$ MpƼ>(qqb6|"⎛? PK /R2CG jdepend/swingui/JDepend$4.class}RJ#A==3_e5"8o QQ "(}l3,]a?Bz/ ]U}ԩ^Xœ#Yd0jcA Lac!OeT0\>ŅP5:Kog=J -"ԫ Č C,ح(SV4~+62n+%RGhR/I1?hjAD _r7'.a 0Xb@ ~PbSanܒIqсi(0L%I۸ze1鮋Ҹ"}_[!Cj42@@#q=KSX0IÆNfYI3t[%DXqE6Cd(8-N>T?RfO5Κ YsI;h[Rc+PK /R2gǗjdepend/swingui/JDepend$5.classunAƿYe E7jzCDLe0Q Ħ}>̰)I9'w2won{(IoS   c1 DE'z$w \D B~ޟwGd|<5](WZ%' F^3{٨PF0fEL5 e EKo\jM3(gxjo[q9%+ilV_$|jr^ C"57.`΅1As}з2>Qu:Z"we 'QXI kQ l23С| o-@53F/o^qxv:vrPK /R2W(–jdepend/swingui/JDepend$6.classu]oAYe ETi 5iAM~X&t2/7M 6260ɞ='s@&< ]ppqPП8cPO\tBǝA)=~PɅLTPH.TwH~zԉ/IS[Ӆ{UrnnT?9C7J_i9eM Ckl\DY3o0ZFPı1E4,y gƱG !.^rB6f^oe8AB׭+ 2$^AV\8{0j|W}[(S]9WZZK8%rWVM ~单U&3Pom ւ 䮑_s=cBglmcj-g?PK /R2Wco<)jdepend/swingui/JDepend$AboutAction.classSn@=4 m64)$ií q(o˹ʖQI _)(aRMbגgFmHZjQՠ8.jt4\e WpU5l2 RC~Qe~mΎjbslaT%cp47k.ƄoxOPmd6A#djT!\*sISOӴZKVɰc*~PSG'!d6bg8SH"׈#_!^f=BF$:Vw%-`$'%ueŴBz9Β]%1ٙUcoQhFeѷ"|F},9]Bst:'QY^Pz3$˾ʾO{=r-ビGa]ZkT+04&w1`b{wO6 0&m|&"v"qwv]^n{|$x <$!Y)|@la$Ie?1%~Er&J.!n(3 &Y6Q W"i\ ~PK /R2mDM5jdepend/swingui/JDepend.classY |T?f&ox@ @0,BȊ "!$HI#nC83DZkRݪhʄMZ[}omk][7K&/_޻sg{|"S+c|GLqLH_qФxAx@|!G|I/5de>+|>7&U>kLW ص<nKihMqIo5i&Mq2p|/'=L ~M:Qc&7QV:# V?aI<#JJkGM?aɟg"~?'E$ ~Τ0(+/WyjN1ML:Guo1y|oۤ=򱇿cwM}y?֏M TZ?3&K_2退 y,ݿ5.|;U AZ?I5lҕb+5_HxC&2yW$HhPl]b;ˆ*+BiIPƙLL:,bV1j<1P~S Ubjr*US|j2{|jOrc|aRl#>5OΧNS P k@> US5&=j Ugz&e hI&-c@*#о}L'^2Mn e$U b,HHGzx*۴Xp8[x"76L\?^;үsH$E  9#8XّimqC4/kM@c)9b: 2ݛ%$&:]1GLrtfgdq;kKvR9ՈVKFs܉ى0AP'e٦$4Y!>-)v =(#!"7ڃ3yg4ĴWV:z-aMXv__sOfؽpH4!\&2U3\.==v؎t,XNwf?+=TQ>mM̌b/O|b5)ۜ(I"=vG #d˂P4#mGȁT -9IWjTS(h"cMj:#vBA(ڌpfZt NMt C|2sq:r2K; ҭwÉt_Inܢȁ:jWѽΝUP8+'1y+s0NcaKcJpJ$bp.½]쉉@Hוf 1 3qN}ƭI'VUS޴iB~">N=\_ͧ%J8F* ;kTј2UY\NapK50L]z<)㐦\3d) x)<{Cޝ2OqIWhs~_H i9iQh}6\a@)Z7;֑T6v7ڃpfY3$ҺlS}1hST{3x1YPEoAl@dY1/FW\RA+ 4*ٽv7Ȍ5#vKe7@4jY~(`%l"T\'"!lҤmy=3Աck-Na癜Szl}aI;BBޟʰ$Ŏ@@]RI4 u2Iɍߥ7+3~Ԣ8/~r{!pC/[|B^P T j%1L3\zS*hx4Et2y&2x3(`5t"EF+hZMAJ)ٯ GYn0&Z7-ZPlPh3Y䣳p tAgz`AۃWz5g. 6w7;`Xƀȅ w j9YA.X`U9C4wu;_'aZ}*hQmuUdx"~ B,R,KWY4Mʳ 45LuG>Wëiݐh5Mz HJ]fȢO!Z NNSa[nЖ3ɅVr AI/môۿdNB,G05Cl:LݵCmF0cg5A|Kt}}'DOr&VQK;Z;kbF6$mܡeq6%iswtC$~(>E[J pOڧ..IZ;O@ s1s\٘3`^ bG8ƒ`<2=\.dM0Ȁ%3< #w҄?~ul* 6z 22OIQd+ȃ-d䙏%T746 )|དJLzNI;>jMؓh%oa>[$uC.}[N']}0cT@|"#|m !ouV?G3'Syy)h{yXGTO#_S9-lp.ڤ hdmi;]+PpnGKHBN]{U?yO}`%vjz̝"g;iV3gA]U|q>w|Jϋ+ʀ개. W(>LpbJ~)TWϼ+%NU}({lEXQ*"KY4AM)j"VTP )?5ZPN UOͤ*k@CtO$  ڃMtYr(mC,*lgl3JA/#[|%TSg&Avn/1 #'7`L"C0h| 9~4Dền vc/ȅx<b/bDly1P-t0tkx~m~4C soݨI+uz!'),qC {LZc-Ek[׸1?PK /R2쁌@Z!jdepend/swingui/PackageNode.classWwU6m%P TJhIӂR$ӦIL,]qC6eѺ/(.6-}9~z4%9=wLo47Gס>-Hb^$xI{1J P$Og9W S栂C|xQKVpSW7˫k>7xyxۋw.A=CF*5B[X;q9 ,s=m@JgC5XbHBYHZ2m8bA*zҙͲbc黬Pgv g$`댔a)0T- P`^H+]Z4I7H:%gc/[^!.jaFtG4Pm@,Ytv0uN'z2){ 3)Xiջ%P3M"ub; C`aH;Uf3$1JwVƈhM%8=!eI-'cnKғJjr U'(GdŒNERʨ|LLo3hZTl@\E3nP7XTlm^=XP$4,H;Ը?#'*N4u9Sq;g1S *NQX:c8%ut;"YgQOXc+֙`ɯp?-!$蠊 S*bzqخŏ'?@ @ywKʪX'ᦱ[oX(/\N C TcbUd5ټt7L4CR (5^중M6@pscxTxiT؁*w@a6rbI4i "54Q*Jєnh6T)ҢFҰ)qgstR֜X:ei'ۭ珃Zt|mOM_:b?Mvف66H ۳ JxNU£J4hqSѮBМ J(Ki_6$8Ҡ純H"ziX`FuP./H p EKn.*A# Pvo礫gtl$zS*[U4~kh/a]ymR"ԅ;Q9= Nc %)|  vr 840, HD ;3xETXaK<9,~?0&T}%ȢC]am7E!ahxB,&/AЏz֎H-<>;{fſ<e%0V,|Ū5}9`(wt$u.D_$T"9O=I\JtPqػ2&}J$ )t05B~]5l3mq"m73ϪY7ˏmtf序 l؂c;>6ڵ+3H/ZbߘĴqC+(& WRTtt_&dXqm_$.ե2}Ș5S;!|KcQT{sVtU^Ղ5C^g 8N,0W<,B/ |{i$/($>5¤VFus X*`.Q@ +ˎ|A ppFdT!xQ/ǸQFX%`MbS^Ӽ]𤇟bR|!_Tun҈޿*Y9dd}f,S֪H &hݦ bi d/ G}1 nG*E3. &0ecrLB~s&Z_p/ws[MICc&f|GUvob,9>$-"Ա;gvoљd-5m藇!(}eCf 2ֆw ꫫkcHK웲 Cte(䏔}ѨEk[1 nplC $8ј:ZY$kiѲA:"3ߙ.GmA'QNi?aSVXA_AYM4, eЇL}۠/c/ L1 [F1EV5g:S.G +~s' ll+m%l|)r yj"7#ٰrB"3ӓjY&͵VǕY%*a}KJT$pRgóc>ؑ;S&;铲 j ^0$ڊ#íEvƮ^Nq1!R/pHݙ55L{ҦSkMODr32gei4:(A>؝K٦")|V z$9l#{L}+1 WP%V8L^_>C-ysu'5Տ BeX 1__ Vι?#/VR7(a3b.q#%+u^H\C"ywpziw3*[,T?U?fGynZAGTz\.zR/hJwp}i`ܥ>P_VJs*`^;_Wï:7Uo6ЋC8}-4ňT~WNVy}E^G~[$ aR;$f{AȩG~~OoO"2~cj2r pꇂ)*oyS˟9wV9^*_lE@(=:E%k-"T3 -NXCRBf'uUa-p؜,tk7qga WJUcfzH py%R}G~+kľ򓬐>yY^̿8L>UJya8YeҘ;@oƑjsQ_5aDn-W^F27&56kMS:ZdZmf!:܋|LqZMD3 /wgb- r~@-+*ڼR!_⻯\.Wx pW&̅_Z\,q%l~m\1ր KqV"-^iɱ6|6x%+GRim`)Lӂ~_T׬-8Eq\Y:{Օ-/g$ФOA1#e'ڪEg=wNh]^9vũ.UNN)2t/p16E7iuaɿ7 DݹT'B-3jVRh_*Mv=i2FTi P#Q8=KVV+$aɁeU 6rY5MF]{bKAa0U䊆#P ?H3T`ct95'<_;pt/Z %IA $;h@eC DW2l]ں5콺`1l":J`plnOn?;{G/kAw~YֱV~AuJ_9XT[|)e(N.a{far0>j/]\%?0a+w:=VׂvXe[N4t:끺C[Ll^_^&gDAj̝ڦi]Y N]+ť[ lqe%օ6BC{G,Ϳ}4~uAoDDy|3[;|Mi1o|]Vgy+}qg6- Ȣ/1dݹefQ2mC=ZS>9d.; E׊T/wNzrgVyy&F%F.z7ʘз7l[lk3y裎O62.RIOQ<3Um%@9iNzsW3bgȭEV:/QDoj#..sBiK ]$bXҤHςs//"۽DCeͯ|~{._'5=0{'2㔭7toB+wY.sDOwE\O8]ʋvut`Vk} -t] ]'֘_ fR7%I(q&lIl)]@Py'P>!Ç9oA`b0|{g(~!C #0 >1(>O0<'x|ça g>,9|EAE̘Na֨`Q1sGR$鵒zjXM>rgUwbԘ22ھt*gj۶YxGLKagm:-UcC! tr;,S+f;>nd=l J=hcy^˞Զ'\dr3mUGwh)YLdtlxĊ9&0M% .˄}$zҵ߿E/w$m1B5 =͓bؘa)>Z_eۖnhh/8ur:;yy BP=n8ymc#9` NSdQ3uZtL+ܔ^KQTuizB3ˌ rrkCD4M^uH!WU| _WяoPT-|;.G*~6$6S1,9u7)~2!mRˉ&dI9~~v?s*~_r%WxZCB ~C!cMVƼF׺\ߊey3ŻƘlCT]Íe,'g~ct]Bs9Di01h9zJV{<wOFɘ( SoIh+]P~A W():NweF%IhBCE!-$lad$,yQIJ~!Xn ? 7=CSVF6[CYccZi%܊v8"!TŔOK* _ rq%[eO sT[%[/uqRmFʯV\S{Ow[vZ'UԊz2Ĕ ƏW^Kcb$\]qX]p}f:iFe7WU;41Elq<9yav/ЧܳX}m(˕xtܗPs+J>(ٽeHs8mC=&wj1 Y,պh>TljT]f b G)hG9 T9k(ЄXEL %a$r" yњby QFfT 8^+˱˧ )i,&7|X>k|^9Q,u4?$,>[)~D+J_(rgҁSRlMIpz3/`R^\Ljr''rKHy $Ȭ76ԂH" 2$,SO` ԑב cqX0cQp-2|i`oߧ~m;E8th@65k΍:^zQORO̍(@(ܨW/N͍(D}e(uznԝE&kB3>u /1?\!_њO[ttcOSs*J}QJ}ý%4\WO ^>Vz6[qr^Ѡot[O0qEmʐ<ҏu/Ep17rz }^ܭݭ[z*0>j|svH>P| zVR; )6ʧzBD 죊7M2%PK /R2 AMETA-INF/PK .R2]E[g+META-INF/MANIFEST.MFPK /R2Ajdepend/PK /R2Ajdepend/framework/PK /R2Ajdepend/swingui/PK /R2A<jdepend/textui/PK /R2Aijdepend/xmlui/PK .R2p &jdepend/framework/AbstractParser.classPK /R2\5jdepend/framework/ClassFileParser$AttributeInfo.classPK /R20q80jdepend/framework/ClassFileParser$Constant.classPK /R2;rɷ9 jdepend/framework/ClassFileParser$FieldOrMethodInfo.classPK /R2L5'jdepend/framework/ClassFileParser.classPK /R2y& ,)jdepend/framework/DependencyConstraint.classPK /R2a #m.jdepend/framework/FileManager.classPK /R2' 25jdepend/framework/JDepend.classPK .R2-dS1^?jdepend/framework/JavaClass$ClassComparator.classPK .R2R!cAjdepend/framework/JavaClass.classPK /R2*aEjdepend/framework/JavaClassBuilder$1.classPK /R2@o(/Gjdepend/framework/JavaClassBuilder.classPK .R2V:#Ojdepend/framework/JavaPackage.classPK /R27[)>Wjdepend/framework/PackageComparator.classPK .R2T&ΰr%Yjdepend/framework/PackageFilter.classPK .R2}ő&]jdepend/framework/ParserListener.classPK /R2ꊸT,^jdepend/framework/PropertyConfigurator.classPK /R2Au#fjdepend/swingui/AboutDialog$1.classPK /R2N#hjdepend/swingui/AboutDialog$2.classPK /R2 !{jjdepend/swingui/AboutDialog.classPK /R2z"npjdepend/swingui/AfferentNode.classPK /R2M1+x: Gsjdepend/swingui/DependTree.classPK /R25c %yjdepend/swingui/DependTreeModel.classPK /R2;>"}jdepend/swingui/EfferentNode.classPK /R28jdepend/swingui/JDepend$1.classPK /R2jdepend/swingui/JDepend$2.classPK /R2NX<jdepend/swingui/JDepend$3.classPK /R2CG Cjdepend/swingui/JDepend$4.classPK /R2gǗ-jdepend/swingui/JDepend$5.classPK /R2W(–jdepend/swingui/JDepend$6.classPK /R2Wco<)ԍjdepend/swingui/JDepend$AboutAction.classPK /R2u(Wjdepend/swingui/JDepend$ExitAction.classPK /R2q-]*jdepend/swingui/JDepend$TreeListener.classPK /R2mDM50jdepend/swingui/JDepend.classPK /R2쁌@Z!jdepend/swingui/PackageNode.classPK /R2d!jdepend/swingui/StatusPanel.classPK /R2gu} 0jdepend/textui/JDepend.classPK /R27U jdepend/xmlui/JDepend.classPK-- >jdepend-2.9.1/test/0000755000000000000000000000000010236624040012606 5ustar rootrootjdepend-2.9.1/test/jdepend/0000755000000000000000000000000010236624040014217 5ustar rootrootjdepend-2.9.1/test/jdepend/framework/0000755000000000000000000000000010236624040016214 5ustar rootrootjdepend-2.9.1/test/jdepend/framework/JarFileParserTest.java0000644000000000000000000000707110236624040022415 0ustar rootrootpackage jdepend.framework; import java.io.File; import java.io.IOException; import java.util.Collection; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JarFileParserTest extends JDependTestCase { private File jarFile; private File zipFile; public JarFileParserTest(String name) { super(name); } protected void setUp() { super.setUp(); jarFile = new File(getTestDataDir() + "test.jar"); zipFile = new File(getTestDataDir() + "test.zip"); } protected void tearDown() { super.tearDown(); } public void testInvalidJarFile() throws IOException { JavaClassBuilder builder = new JavaClassBuilder(); File bogusFile = new File(getTestDataDir() + "bogus.jar"); try { builder.buildClasses(bogusFile); fail("Should raise IOException"); } catch (IOException expected) { assertTrue(true); } } public void testInvalidZipFile() throws IOException { JavaClassBuilder builder = new JavaClassBuilder(); File bogusFile = new File(getTestDataDir() + "bogus.zip"); try { builder.buildClasses(bogusFile); fail("Should raise IOException"); } catch (IOException expected) { assertTrue(true); } } public void testJarFile() throws IOException { JavaClassBuilder builder = new JavaClassBuilder(); Collection classes = builder.buildClasses(jarFile); assertEquals(5, classes.size()); assertClassesExist(classes); assertInnerClassesExist(classes); } public void testJarFileWithoutInnerClasses() throws IOException { FileManager fm = new FileManager(); fm.acceptInnerClasses(false); JavaClassBuilder builder = new JavaClassBuilder(fm); Collection classes = builder.buildClasses(jarFile); assertEquals(4, classes.size()); assertClassesExist(classes); } public void testZipFile() throws IOException { JavaClassBuilder builder = new JavaClassBuilder(); Collection classes = builder.buildClasses(zipFile); assertEquals(5, classes.size()); assertClassesExist(classes); assertInnerClassesExist(classes); } public void testZipFileWithoutInnerClasses() throws IOException { FileManager fm = new FileManager(); fm.acceptInnerClasses(false); JavaClassBuilder builder = new JavaClassBuilder(fm); Collection classes = builder.buildClasses(zipFile); assertEquals(4, classes.size()); assertClassesExist(classes); } public void testCountClasses() throws IOException { JDepend jdepend = new JDepend(); jdepend.addDirectory(getTestDataDir()); jdepend.analyzeInnerClasses(true); assertEquals(10, jdepend.countClasses()); jdepend.analyzeInnerClasses(false); assertEquals(8, jdepend.countClasses()); } private void assertClassesExist(Collection classes) { assertTrue(classes.contains(new JavaClass( "jdepend.framework.ExampleAbstractClass"))); assertTrue(classes.contains(new JavaClass( "jdepend.framework.ExampleInterface"))); assertTrue(classes.contains(new JavaClass( "jdepend.framework.ExampleConcreteClass"))); } private void assertInnerClassesExist(Collection classes) { assertTrue(classes.contains(new JavaClass( "jdepend.framework.ExampleConcreteClass$ExampleInnerClass"))); } }jdepend-2.9.1/test/jdepend/framework/ConstraintTest.java0000644000000000000000000000525510236624040022052 0ustar rootrootpackage jdepend.framework; import java.io.IOException; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class ConstraintTest extends JDependTestCase { private JDepend jdepend; public ConstraintTest(String name) { super(name); } protected void setUp() { super.setUp(); PackageFilter filter = new PackageFilter(); filter.addPackage("java.*"); filter.addPackage("javax.*"); jdepend = new JDepend(filter); } public void testMatchPass() { DependencyConstraint constraint = new DependencyConstraint(); JavaPackage expectedA = constraint.addPackage("A"); JavaPackage expectedB = constraint.addPackage("B"); expectedA.dependsUpon(expectedB); JavaPackage actualA = new JavaPackage("A"); JavaPackage actualB = new JavaPackage("B"); actualA.dependsUpon(actualB); jdepend.addPackage(actualA); jdepend.addPackage(actualB); assertEquals(true, jdepend.dependencyMatch(constraint)); } public void testMatchFail() { DependencyConstraint constraint = new DependencyConstraint(); JavaPackage expectedA = constraint.addPackage("A"); JavaPackage expectedB = constraint.addPackage("B"); JavaPackage expectedC = constraint.addPackage("C"); expectedA.dependsUpon(expectedB); JavaPackage actualA = new JavaPackage("A"); JavaPackage actualB = new JavaPackage("B"); JavaPackage actualC = new JavaPackage("C"); actualA.dependsUpon(actualB); actualA.dependsUpon(actualC); jdepend.addPackage(actualA); jdepend.addPackage(actualB); jdepend.addPackage(actualC); assertEquals(false, jdepend.dependencyMatch(constraint)); } public void testJDependConstraints() throws IOException { jdepend.addDirectory(getBuildDir()); jdepend.analyze(); DependencyConstraint constraint = new DependencyConstraint(); JavaPackage junitframework = constraint.addPackage("junit.framework"); JavaPackage junitui = constraint.addPackage("junit.textui"); JavaPackage framework = constraint.addPackage("jdepend.framework"); JavaPackage text = constraint.addPackage("jdepend.textui"); JavaPackage xml = constraint.addPackage("jdepend.xmlui"); JavaPackage swing = constraint.addPackage("jdepend.swingui"); framework.dependsUpon(junitframework); framework.dependsUpon(junitui); text.dependsUpon(framework); xml.dependsUpon(text); swing.dependsUpon(framework); assertEquals(true, jdepend.dependencyMatch(constraint)); } }jdepend-2.9.1/test/jdepend/framework/CollectAllCyclesTest.java0000644000000000000000000001250710236624040023105 0ustar rootrootpackage jdepend.framework; import java.util.ArrayList; import java.util.List; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class CollectAllCyclesTest extends JDependTestCase { public CollectAllCyclesTest(String name) { super(name); } public void testNoCycles() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); a.dependsUpon(b); List aCycles = new ArrayList(); assertEquals(false, a.containsCycle()); assertEquals(false, a.collectAllCycles(aCycles)); assertListEquals(aCycles, new String[] {}); List bCycles = new ArrayList(); assertEquals(false, b.containsCycle()); assertEquals(false, b.collectAllCycles(bCycles)); assertListEquals(bCycles, new String[] {}); } public void test2Node1BranchCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); a.dependsUpon(b); b.dependsUpon(a); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectAllCycles(aCycles)); assertListEquals(aCycles, new String[] {"A", "B", "A"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectAllCycles(bCycles)); assertListEquals(bCycles, new String[] {"B", "A", "B"}); } public void test3Node1BranchCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); JavaPackage c = new JavaPackage("C"); a.dependsUpon(b); b.dependsUpon(c); c.dependsUpon(a); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectAllCycles(aCycles)); assertListEquals(aCycles, new String[] {"A", "B", "C", "A"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectAllCycles(bCycles)); assertListEquals(bCycles, new String[] {"B", "C", "A", "B"}); List cCycles = new ArrayList(); assertEquals(true, c.containsCycle()); assertEquals(true, c.collectAllCycles(cCycles)); assertListEquals(cCycles, new String[] {"C", "A", "B", "C"}); } public void test3Node1BranchSubCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); JavaPackage c = new JavaPackage("C"); a.dependsUpon(b); b.dependsUpon(c); c.dependsUpon(b); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectAllCycles(aCycles)); assertListEquals(aCycles, new String[] {"A", "B", "C", "B"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectAllCycles(bCycles)); assertListEquals(bCycles, new String[] {"B", "C", "B"}); List cCycles = new ArrayList(); assertEquals(true, c.containsCycle()); assertEquals(true, c.collectAllCycles(cCycles)); assertListEquals(cCycles, new String[] {"C", "B", "C"}); } public void test3Node2BranchCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); JavaPackage c = new JavaPackage("C"); a.dependsUpon(b); b.dependsUpon(a); a.dependsUpon(c); c.dependsUpon(a); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectAllCycles(aCycles)); assertListEquals(aCycles, new String[] {"A", "B", "A", "C", "A"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectAllCycles(bCycles)); assertListEquals(bCycles, new String[] {"B", "A", "B", "C", "A"}); List cCycles = new ArrayList(); assertEquals(true, c.containsCycle()); assertEquals(true, c.collectAllCycles(cCycles)); assertListEquals(cCycles, new String[] {"C", "A", "B", "A", "C"}); } public void test5Node2BranchCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); JavaPackage c = new JavaPackage("C"); JavaPackage d = new JavaPackage("D"); JavaPackage e = new JavaPackage("E"); a.dependsUpon(b); b.dependsUpon(c); c.dependsUpon(a); a.dependsUpon(d); d.dependsUpon(e); e.dependsUpon(a); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectAllCycles(aCycles)); assertListEquals(aCycles, new String[] {"A", "B", "C", "A", "D", "E", "A"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectAllCycles(bCycles)); assertListEquals(bCycles, new String[] {"B", "C", "A", "B", "D", "E", "A"}); List cCycles = new ArrayList(); assertEquals(true, c.containsCycle()); assertEquals(true, c.collectAllCycles(cCycles)); assertListEquals(cCycles, new String[] {"C", "A", "B", "C", "D", "E", "A"}); List dCycles = new ArrayList(); assertEquals(true, d.containsCycle()); assertEquals(true, d.collectAllCycles(dCycles)); assertListEquals(dCycles, new String[] {"D", "E", "A", "B", "C", "A" , "D"}); List eCycles = new ArrayList(); assertEquals(true, e.containsCycle()); assertEquals(true, e.collectAllCycles(eCycles)); assertListEquals(eCycles, new String[] {"E", "A", "B", "C", "A", "D", "E"}); } protected void assertListEquals(List list, String names[]) { assertEquals(names.length, list.size()); for (int i=0; i < names.length; i++) { assertEquals(names[i], ((JavaPackage)list.get(i)).getName()); } } } jdepend-2.9.1/test/jdepend/framework/ExampleConcreteClass.java0000644000000000000000000000210710236624040023123 0ustar rootrootpackage jdepend.framework; import java.math.BigDecimal; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class ExampleConcreteClass extends ExampleAbstractClass { private java.sql.Statement[] statements; public ExampleConcreteClass() { } public void a() { try { java.net.URL url = new java.net.URL("http://www.clarkware.com"); } catch (Exception e) { } } public java.util.Vector b(String[] s, java.text.NumberFormat nf) { return null; } public void c(BigDecimal bd, byte[] bytes) throws java.rmi.RemoteException { int[] a = { 1, 2, 3}; int[][] b = { { 1, 2}, { 3, 4}, { 5, 6}}; } public java.io.File[] d() throws java.io.IOException { java.util.jar.JarFile[] files = new java.util.jar.JarFile[1]; return new java.io.File[10]; } public java.lang.String[] e() { java.lang.String[] strings = new java.lang.String[1]; return strings; } public class ExampleInnerClass { } } class ExamplePackageClass { }jdepend-2.9.1/test/jdepend/framework/ClassFileParserTest.java0000644000000000000000000001231410236624040022742 0ustar rootrootpackage jdepend.framework; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class ClassFileParserTest extends JDependTestCase { private ClassFileParser parser; public ClassFileParserTest(String name) { super(name); } protected void setUp() { super.setUp(); PackageFilter filter = new PackageFilter(new ArrayList()); parser = new ClassFileParser(filter); } protected void tearDown() { super.tearDown(); } public void testInvalidClassFile() { File f = new File(getTestDir() + getPackageSubDir() + "ExampleTest.java"); try { parser.parse(f); fail("Invalid class file: Should raise IOException"); } catch (IOException expected) { assertTrue(true); } } public void testInterfaceClass() throws IOException { File f = new File(getBuildDir() + getPackageSubDir() + "ExampleInterface.class"); JavaClass clazz = parser.parse(f); assertTrue(clazz.isAbstract()); assertEquals("jdepend.framework.ExampleInterface", clazz.getName()); assertEquals("ExampleInterface.java", clazz.getSourceFile()); Collection imports = clazz.getImportedPackages(); assertEquals(6, imports.size()); assertTrue(imports.contains(new JavaPackage("java.math"))); assertTrue(imports.contains(new JavaPackage("java.text"))); assertTrue(imports.contains(new JavaPackage("java.lang"))); assertTrue(imports.contains(new JavaPackage("java.io"))); assertTrue(imports.contains(new JavaPackage("java.rmi"))); assertTrue(imports.contains(new JavaPackage("java.util"))); } public void testAbstractClass() throws IOException { File f = new File(getBuildDir() + getPackageSubDir() + "ExampleAbstractClass.class"); JavaClass clazz = parser.parse(f); assertTrue(clazz.isAbstract()); assertEquals("jdepend.framework.ExampleAbstractClass", clazz.getName()); assertEquals("ExampleAbstractClass.java", clazz.getSourceFile()); Collection imports = clazz.getImportedPackages(); assertEquals(7, imports.size()); assertTrue(imports.contains(new JavaPackage("java.math"))); assertTrue(imports.contains(new JavaPackage("java.text"))); assertTrue(imports.contains(new JavaPackage("java.lang"))); assertTrue(imports.contains(new JavaPackage("java.lang.reflect"))); assertTrue(imports.contains(new JavaPackage("java.io"))); assertTrue(imports.contains(new JavaPackage("java.rmi"))); assertTrue(imports.contains(new JavaPackage("java.util"))); } public void testConcreteClass() throws IOException { File f = new File(getBuildDir() + getPackageSubDir() + "ExampleConcreteClass.class"); JavaClass clazz = parser.parse(f); assertFalse(clazz.isAbstract()); assertEquals("jdepend.framework.ExampleConcreteClass", clazz.getName()); assertEquals("ExampleConcreteClass.java", clazz.getSourceFile()); Collection imports = clazz.getImportedPackages(); assertEquals(9, imports.size()); assertTrue(imports.contains(new JavaPackage("java.net"))); assertTrue(imports.contains(new JavaPackage("java.text"))); assertTrue(imports.contains(new JavaPackage("java.sql"))); assertTrue(imports.contains(new JavaPackage("java.lang"))); assertTrue(imports.contains(new JavaPackage("java.io"))); assertTrue(imports.contains(new JavaPackage("java.rmi"))); assertTrue(imports.contains(new JavaPackage("java.util"))); assertTrue(imports.contains(new JavaPackage("java.util.jar"))); assertTrue(imports.contains(new JavaPackage("java.math"))); } public void testInnerClass() throws IOException { File f = new File(getBuildDir() + getPackageSubDir() + "ExampleConcreteClass$ExampleInnerClass.class"); JavaClass clazz = parser.parse(f); assertFalse(clazz.isAbstract()); assertEquals("jdepend.framework.ExampleConcreteClass$ExampleInnerClass", clazz.getName()); assertEquals("ExampleConcreteClass.java", clazz.getSourceFile()); Collection imports = clazz.getImportedPackages(); assertEquals(1, imports.size()); assertTrue(imports.contains(new JavaPackage("java.lang"))); } public void testPackageClass() throws IOException { File f = new File(getBuildDir() + getPackageSubDir() + "ExamplePackageClass.class"); JavaClass clazz = parser.parse(f); assertFalse(clazz.isAbstract()); assertEquals("jdepend.framework.ExamplePackageClass", clazz.getName()); assertEquals("ExampleConcreteClass.java", clazz.getSourceFile()); Collection imports = clazz.getImportedPackages(); assertEquals(1, imports.size()); assertTrue(imports.contains(new JavaPackage("java.lang"))); } }jdepend-2.9.1/test/jdepend/framework/MetricTest.java0000644000000000000000000001005010236624040021136 0ustar rootrootpackage jdepend.framework; import java.io.IOException; import java.text.NumberFormat; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class MetricTest extends JDependTestCase { private JDepend jdepend; private static NumberFormat formatter; static { formatter = NumberFormat.getInstance(); formatter.setMaximumFractionDigits(2); } public MetricTest(String name) { super(name); } protected void setUp() { super.setUp(); PackageFilter filter = new PackageFilter(); filter.addPackage("java.*"); filter.addPackage("javax.*"); jdepend = new JDepend(filter); jdepend.analyzeInnerClasses(false); } protected void tearDown() { super.tearDown(); } public void testAnalyzeClassFiles() throws IOException { jdepend.addDirectory(getBuildDir()); assertAnalyzePackages(); } private void assertAnalyzePackages() { assertEquals(39, jdepend.countClasses()); PackageFilter filter = jdepend.getFilter(); filter.addPackage("junit.*"); jdepend.analyze(); assertFrameworkPackage(); assertTextUIPackage(); assertSwingUIPackage(); assertXmlUIPackage(); } private void assertFrameworkPackage() { JavaPackage p = jdepend.getPackage("jdepend.framework"); assertNotNull(p); assertEquals(25, p.getConcreteClassCount()); assertEquals(4, p.getAbstractClassCount()); assertEquals(3, p.afferentCoupling()); assertEquals(0, p.efferentCoupling()); assertEquals(format(0.14f), format(p.abstractness())); assertEquals(format(0.0f), format(p.instability())); assertEquals(format(0.86f), format(p.distance())); assertEquals(1, p.getVolatility()); } private void assertTextUIPackage() { JavaPackage p = jdepend.getPackage("jdepend.textui"); assertNotNull(p); assertEquals(1, p.getConcreteClassCount()); assertEquals(0, p.getAbstractClassCount()); assertEquals(1, p.efferentCoupling()); assertEquals("0", format(p.abstractness())); assertEquals(1, p.afferentCoupling()); assertEquals(format(0.5f), format(p.instability())); assertEquals(format(0.5f), format(p.distance())); assertEquals(1, p.getVolatility()); } private void assertSwingUIPackage() { JavaPackage p = jdepend.getPackage("jdepend.swingui"); assertNotNull(p); assertEquals(7, p.getConcreteClassCount()); assertEquals(1, p.getAbstractClassCount()); assertEquals(0, p.afferentCoupling()); assertEquals(1, p.efferentCoupling()); assertEquals(format(0.12f), format(p.abstractness())); assertEquals("1", format(p.instability())); assertEquals(format(0.12f), format(p.distance())); assertEquals(1, p.getVolatility()); } private void assertXmlUIPackage() { JavaPackage p = jdepend.getPackage("jdepend.xmlui"); assertNotNull(p); assertEquals(1, p.getConcreteClassCount()); assertEquals(0, p.getAbstractClassCount()); assertEquals(0, p.afferentCoupling()); assertEquals(2, p.efferentCoupling()); assertEquals(format(0.0f), format(p.abstractness())); assertEquals("1", format(p.instability())); assertEquals(format(0.0f), format(p.distance())); assertEquals(1, p.getVolatility()); } public void testConfiguredVolatility() throws IOException { jdepend.addDirectory(getBuildDir()); JavaPackage pkg = new JavaPackage("jdepend.swingui"); pkg.setVolatility(0); jdepend.addPackage(pkg); jdepend.analyze(); JavaPackage analyzedPkg = jdepend.getPackage(pkg.getName()); assertEquals(0, analyzedPkg.getVolatility()); assertEquals(format(0.0f), format(analyzedPkg.distance())); assertEquals(7, analyzedPkg.getConcreteClassCount()); } private String format(float f) { return formatter.format(f); } }jdepend-2.9.1/test/jdepend/framework/ExampleTest.java0000644000000000000000000001007210236624040021312 0ustar rootrootpackage jdepend.framework; import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.Iterator; import junit.framework.TestCase; /** * The ExampleTest is an example TestCase * that demonstrates tests for measuring the distance from the * main sequence (D), package dependency constraints, and the * existence of cyclic package dependencies. *

* This test analyzes the JDepend class files. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class ExampleTest extends TestCase { private JDepend jdepend; public String jdependHomeDirectory; public ExampleTest(String name) { super(name); } protected void setUp() throws IOException { jdependHomeDirectory = System.getProperty("jdepend.home"); if (jdependHomeDirectory == null) { fail("Property 'jdepend.home' not defined"); } PackageFilter filter = new PackageFilter(); filter.addPackage("java.*"); filter.addPackage("javax.*"); jdepend = new JDepend(filter); String classesDir = jdependHomeDirectory + File.separator + "build"; jdepend.addDirectory(classesDir); } /** * Tests the conformance of a single package to a distance * from the main sequence (D) within a tolerance. */ public void testOnePackageDistance() { double ideal = 0.0; double tolerance = 0.8; jdepend.analyze(); JavaPackage p = jdepend.getPackage("jdepend.framework"); assertEquals("Distance exceeded: " + p.getName(), ideal, p.distance(), tolerance); } /** * Tests that a single package does not contain any * package dependency cycles. */ public void testOnePackageHasNoCycles() { jdepend.analyze(); JavaPackage p = jdepend.getPackage("jdepend.framework"); assertEquals("Cycles exist: " + p.getName(), false, p.containsCycle()); } /** * Tests the conformance of all analyzed packages to a * distance from the main sequence (D) within a tolerance. */ public void testAllPackagesDistance() { double ideal = 0.0; double tolerance = 1.0; Collection packages = jdepend.analyze(); for (Iterator iter = packages.iterator(); iter.hasNext();) { JavaPackage p = (JavaPackage)iter.next(); assertEquals("Distance exceeded: " + p.getName(), ideal, p.distance(), tolerance); } } /** * Tests that a package dependency cycle does not exist * for any of the analyzed packages. */ public void testAllPackagesHaveNoCycles() { Collection packages = jdepend.analyze(); assertEquals("Cycles exist", false, jdepend.containsCycles()); } /** * Tests that a package dependency constraint is matched * for the analyzed packages. *

* Fails if any package dependency other than those declared * in the dependency constraints are detected. */ public void testDependencyConstraint() { DependencyConstraint constraint = new DependencyConstraint(); JavaPackage junitframework = constraint.addPackage("junit.framework"); JavaPackage junitui = constraint.addPackage("junit.textui"); JavaPackage framework = constraint.addPackage("jdepend.framework"); JavaPackage text = constraint.addPackage("jdepend.textui"); JavaPackage xml = constraint.addPackage("jdepend.xmlui"); JavaPackage swing = constraint.addPackage("jdepend.swingui"); framework.dependsUpon(junitframework); framework.dependsUpon(junitui); text.dependsUpon(framework); xml.dependsUpon(text); swing.dependsUpon(framework); jdepend.analyze(); assertEquals("Constraint mismatch", true, jdepend.dependencyMatch(constraint)); } public static void main(String[] args) { junit.textui.TestRunner.run(ExampleTest.class); } }jdepend-2.9.1/test/jdepend/framework/ComponentTest.java0000644000000000000000000000660210236624040021665 0ustar rootrootpackage jdepend.framework; import java.io.IOException; import java.text.NumberFormat; import java.util.Collection; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class ComponentTest extends JDependTestCase { private JDepend jdepend; private static NumberFormat formatter; static { formatter = NumberFormat.getInstance(); formatter.setMaximumFractionDigits(2); } public ComponentTest(String name) { super(name); } protected void setUp() { super.setUp(); jdepend = new JDepend(); jdepend.analyzeInnerClasses(false); } protected void tearDown() { super.tearDown(); } public void testJDependComponents() throws IOException { jdepend.setComponents("jdepend,junit,java,javax"); jdepend.addDirectory(getBuildDir()); jdepend.analyze(); Collection packages = jdepend.getPackages(); assertEquals(4, packages.size()); assertJDependPackage(); assertJUnitPackage(); assertJavaPackage(); assertJavaxPackage(); } private void assertJDependPackage() { JavaPackage p = jdepend.getPackage("jdepend"); assertEquals("jdepend", p.getName()); assertEquals(34, p.getConcreteClassCount()); assertEquals(5, p.getAbstractClassCount()); assertEquals(0, p.afferentCoupling()); assertEquals(3, p.efferentCoupling()); assertEquals(format(0.13f), format(p.abstractness())); assertEquals("1", format(p.instability())); assertEquals(format(0.13f), format(p.distance())); assertEquals(1, p.getVolatility()); Collection efferents = p.getEfferents(); assertEquals(3, efferents.size()); assertTrue(efferents.contains(new JavaPackage("java"))); assertTrue(efferents.contains(new JavaPackage("javax"))); assertTrue(efferents.contains(new JavaPackage("junit"))); Collection afferents = p.getAfferents(); assertEquals(0, afferents.size()); } private void assertJUnitPackage() { JavaPackage p = jdepend.getPackage("junit"); assertEquals("junit", p.getName()); Collection afferents = p.getAfferents(); assertEquals(1, afferents.size()); assertTrue(afferents.contains(new JavaPackage("jdepend"))); Collection efferents = p.getEfferents(); assertEquals(0, efferents.size()); } private void assertJavaPackage() { JavaPackage p = jdepend.getPackage("java"); assertEquals("java", p.getName()); Collection afferents = p.getAfferents(); assertEquals(1, afferents.size()); assertTrue(afferents.contains(new JavaPackage("jdepend"))); Collection efferents = p.getEfferents(); assertEquals(0, efferents.size()); } private void assertJavaxPackage() { JavaPackage p = jdepend.getPackage("javax"); assertEquals("javax", p.getName()); Collection afferents = p.getAfferents(); assertEquals(1, afferents.size()); assertTrue(afferents.contains(new JavaPackage("jdepend"))); Collection efferents = p.getEfferents(); assertEquals(0, efferents.size()); } private String format(float f) { return formatter.format(f); } }jdepend-2.9.1/test/jdepend/framework/ExampleAbstractClass.java0000644000000000000000000000116710236624040023131 0ustar rootrootpackage jdepend.framework; import java.math.BigDecimal; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public abstract class ExampleAbstractClass implements ExampleInterface, java.io.Serializable { private java.lang.reflect.Method method; public ExampleAbstractClass() { } public void a() { java.net.URL url; } public java.util.Vector b(String[] s, java.text.NumberFormat nf) { return null; } public void c(BigDecimal bd, byte[] b) throws java.rmi.RemoteException { } public abstract java.io.File[] d() throws java.io.IOException; }jdepend-2.9.1/test/jdepend/framework/PropertyConfiguratorTest.java0000644000000000000000000000345610236624040024136 0ustar rootrootpackage jdepend.framework; import java.io.File; import java.io.IOException; import java.util.Collection; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class PropertyConfiguratorTest extends JDependTestCase { public PropertyConfiguratorTest(String name) { super(name); } protected void setUp() { super.setUp(); System.setProperty("user.home", getTestDataDir()); } protected void tearDown() { super.tearDown(); } public void testDefaultFilters() { PropertyConfigurator c = new PropertyConfigurator(); assertFiltersExist(c.getFilteredPackages()); assertFalse(c.getAnalyzeInnerClasses()); } public void testFiltersFromFile() throws IOException { String file = getTestDataDir() + "jdepend.properties"; PropertyConfigurator c = new PropertyConfigurator(new File(file)); assertFiltersExist(c.getFilteredPackages()); assertFalse(c.getAnalyzeInnerClasses()); } private void assertFiltersExist(Collection filters) { assertEquals(5, filters.size()); assertTrue(filters.contains("java.*")); assertTrue(filters.contains("javax.*")); assertTrue(filters.contains("sun.*")); assertTrue(filters.contains("com.sun.*")); assertTrue(filters.contains("com.xyz.tests.*")); } public void testDefaultPackages() throws IOException { JDepend j = new JDepend(); JavaPackage pkg = j.getPackage("com.xyz.a.neverchanges"); assertNotNull(pkg); assertEquals(0, pkg.getVolatility()); pkg = j.getPackage("com.xyz.b.neverchanges"); assertNotNull(pkg); assertEquals(0, pkg.getVolatility()); pkg = j.getPackage("com.xyz.c.neverchanges"); assertNull(pkg); } }jdepend-2.9.1/test/jdepend/framework/CycleTest.java0000644000000000000000000001422710236624040020764 0ustar rootrootpackage jdepend.framework; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class CycleTest extends JDependTestCase { public CycleTest(String name) { super(name); } public void testNoCycles() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); a.dependsUpon(b); List aCycles = new ArrayList(); assertEquals(false, a.containsCycle()); assertEquals(false, a.collectCycle(aCycles)); assertListEquals(aCycles, new String[] {}); List bCycles = new ArrayList(); assertEquals(false, b.containsCycle()); assertEquals(false, b.collectCycle(bCycles)); assertListEquals(bCycles, new String[] {}); } public void test2Node1BranchCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); a.dependsUpon(b); b.dependsUpon(a); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectCycle(aCycles)); assertListEquals(aCycles, new String[] { "A", "B", "A"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectCycle(bCycles)); assertListEquals(bCycles, new String[] { "B", "A", "B"}); } public void test3Node1BranchCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); JavaPackage c = new JavaPackage("C"); a.dependsUpon(b); b.dependsUpon(c); c.dependsUpon(a); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectCycle(aCycles)); assertListEquals(aCycles, new String[] { "A", "B", "C", "A"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectCycle(bCycles)); assertListEquals(bCycles, new String[] { "B", "C", "A", "B"}); List cCycles = new ArrayList(); assertEquals(true, c.containsCycle()); assertEquals(true, c.collectCycle(cCycles)); assertListEquals(cCycles, new String[] { "C", "A", "B", "C"}); } public void test3Node1BranchSubCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); JavaPackage c = new JavaPackage("C"); a.dependsUpon(b); b.dependsUpon(c); c.dependsUpon(b); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectCycle(aCycles)); assertListEquals(aCycles, new String[] { "A", "B", "C", "B"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectCycle(bCycles)); assertListEquals(bCycles, new String[] { "B", "C", "B"}); List cCycles = new ArrayList(); assertEquals(true, c.containsCycle()); assertEquals(true, c.collectCycle(cCycles)); assertListEquals(cCycles, new String[] { "C", "B", "C"}); } public void test3Node2BranchCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); JavaPackage c = new JavaPackage("C"); a.dependsUpon(b); b.dependsUpon(a); a.dependsUpon(c); c.dependsUpon(a); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectCycle(aCycles)); assertListEquals(aCycles, new String[] { "A", "B", "A"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectCycle(bCycles)); assertListEquals(bCycles, new String[] { "B", "A", "B"}); List cCycles = new ArrayList(); assertEquals(true, c.containsCycle()); assertEquals(true, c.collectCycle(cCycles)); assertListEquals(cCycles, new String[] { "C", "A", "B", "A"}); } public void test5Node2BranchCycle() { JavaPackage a = new JavaPackage("A"); JavaPackage b = new JavaPackage("B"); JavaPackage c = new JavaPackage("C"); JavaPackage d = new JavaPackage("D"); JavaPackage e = new JavaPackage("E"); a.dependsUpon(b); b.dependsUpon(c); c.dependsUpon(a); a.dependsUpon(d); d.dependsUpon(e); e.dependsUpon(a); List aCycles = new ArrayList(); assertEquals(true, a.containsCycle()); assertEquals(true, a.collectCycle(aCycles)); assertListEquals(aCycles, new String[] { "A", "B", "C", "A"}); List bCycles = new ArrayList(); assertEquals(true, b.containsCycle()); assertEquals(true, b.collectCycle(bCycles)); assertListEquals(bCycles, new String[] { "B", "C", "A", "B"}); List cCycles = new ArrayList(); assertEquals(true, c.containsCycle()); assertEquals(true, c.collectCycle(cCycles)); assertListEquals(cCycles, new String[] { "C", "A", "B", "C"}); List dCycles = new ArrayList(); assertEquals(true, d.containsCycle()); assertEquals(true, d.collectCycle(dCycles)); assertListEquals(dCycles, new String[] { "D", "E", "A", "B", "C", "A"}); List eCycles = new ArrayList(); assertEquals(true, e.containsCycle()); assertEquals(true, e.collectCycle(eCycles)); assertListEquals(eCycles, new String[] { "E", "A", "B", "C", "A"}); } protected void assertListEquals(List list, String names[]) { assertEquals(names.length, list.size()); for (int i = 0; i < names.length; i++) { assertEquals(names[i], ((JavaPackage) list.get(i)).getName()); } } protected void printCycles(List list) { Iterator i = list.iterator(); while (i.hasNext()) { JavaPackage p = (JavaPackage) i.next(); if (i.hasNext()) { System.out.print(p.getName() + "->"); } else { System.out.println(p.getName()); } } } }jdepend-2.9.1/test/jdepend/framework/AllTests.java0000644000000000000000000000171410236624040020615 0ustar rootrootpackage jdepend.framework; import junit.framework.Test; import junit.framework.TestSuite; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class AllTests { public static Test suite() { TestSuite suite = new TestSuite("JDepend Tests"); suite.addTestSuite(ClassFileParserTest.class); suite.addTestSuite(ComponentTest.class); suite.addTestSuite(JarFileParserTest.class); suite.addTestSuite(ConstraintTest.class); suite.addTestSuite(CycleTest.class); suite.addTestSuite(CollectAllCyclesTest.class); suite.addTestSuite(FileManagerTest.class); suite.addTestSuite(FilterTest.class); suite.addTestSuite(MetricTest.class); suite.addTestSuite(PropertyConfiguratorTest.class); suite.addTestSuite(ExampleTest.class); return suite; } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } }jdepend-2.9.1/test/jdepend/framework/FilterTest.java0000644000000000000000000000365110236624040021151 0ustar rootrootpackage jdepend.framework; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class FilterTest extends JDependTestCase { public FilterTest(String name) { super(name); } protected void setUp() { super.setUp(); System.setProperty("user.home", getTestDataDir()); } protected void tearDown() { super.tearDown(); } public void testDefault() { PackageFilter filter = new PackageFilter(); assertEquals(5, filter.getFilters().size()); assertFiltersExist(filter); } public void testFile() throws IOException { String filterFile = getTestDataDir() + "jdepend.properties"; PackageFilter filter = new PackageFilter(new File(filterFile)); assertEquals(5, filter.getFilters().size()); assertFiltersExist(filter); } public void testCollection() throws IOException { Collection filters = new ArrayList(); filters.add("java.*"); filters.add("javax.*"); filters.add("sun.*"); filters.add("com.sun.*"); filters.add("com.xyz.tests.*"); PackageFilter filter = new PackageFilter(filters); assertEquals(5, filter.getFilters().size()); assertFiltersExist(filter); } public void testCollectionSubset() { Collection filters = new ArrayList(); filters.add("com.xyz"); PackageFilter filter = new PackageFilter(filters); assertEquals(1, filter.getFilters().size()); } private void assertFiltersExist(PackageFilter filter) { assertFalse(filter.accept("java.lang")); assertFalse(filter.accept("javax.ejb")); assertTrue(filter.accept("com.xyz.tests")); assertFalse(filter.accept("com.xyz.tests.a")); assertTrue(filter.accept("com.xyz.ejb")); } }jdepend-2.9.1/test/jdepend/framework/FileManagerTest.java0000644000000000000000000000523010236624040022071 0ustar rootrootpackage jdepend.framework; import java.io.File; import java.io.IOException; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class FileManagerTest extends JDependTestCase { private FileManager fileManager; public FileManagerTest(String name) { super(name); } protected void setUp() { super.setUp(); fileManager = new FileManager(); fileManager.acceptInnerClasses(false); } protected void tearDown() { super.tearDown(); } public void testEmptyFileManager() { assertEquals(0, fileManager.extractFiles().size()); } public void testBuildDirectory() throws IOException { fileManager.addDirectory(getBuildDir()); assertEquals(39, fileManager.extractFiles().size()); } public void testNonExistentDirectory() { try { fileManager.addDirectory(getBuildDir() + "junk"); fail("Non-existent directory: Should raise IOException"); } catch (IOException expected) { assertTrue(true); } } public void testInvalidDirectory() { String file = getTestDir() + getPackageSubDir() + "ExampleTest.java"; try { fileManager.addDirectory(file); fail("Invalid directory: Should raise IOException"); } catch (IOException expected) { assertTrue(true); } } public void testClassFile() throws IOException { File f = new File(getBuildDir() + getPackageSubDir() + "JDepend.class"); assertEquals(true, new FileManager().acceptClassFile(f)); } public void testNonExistentClassFile() { File f = new File(getBuildDir() + "JDepend.class"); assertEquals(false, new FileManager().acceptClassFile(f)); } public void testInvalidClassFile() { File f = new File(getHomeDir() + "build.xml"); assertEquals(false, new FileManager().acceptClassFile(f)); } public void testJar() throws IOException { File f = File.createTempFile("bogus", ".jar", new File(getTestDataDir())); fileManager.addDirectory(f.getPath()); f.deleteOnExit(); } public void testZip() throws IOException { File f = File.createTempFile("bogus", ".zip", new File(getTestDataDir())); fileManager.addDirectory(f.getPath()); f.deleteOnExit(); } public void testWar() throws IOException { File f = File.createTempFile("bogus", ".war", new File(getTestDataDir())); fileManager.addDirectory(f.getPath()); f.deleteOnExit(); } }jdepend-2.9.1/test/jdepend/framework/JDependTestCase.java0000644000000000000000000000272610236624040022033 0ustar rootrootpackage jdepend.framework; import java.io.*; import junit.framework.*; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JDependTestCase extends TestCase { private String homeDir; private String testDir; private String testDataDir; private String buildDir; private String packageSubDir; private String originalUserHome; public JDependTestCase(String name) { super(name); } protected void setUp() { homeDir = System.getProperty("jdepend.home"); if (homeDir == null) { fail("Property 'jdepend.home' not defined"); } homeDir = homeDir + File.separator; testDir = homeDir + File.separator + "test" + File.separator; testDataDir = testDir + "data" + File.separator; buildDir = homeDir + "build" + File.separator; packageSubDir = "jdepend" + File.separator + "framework" + File.separator; originalUserHome = System.getProperty("user.home"); } protected void tearDown() { System.setProperty("user.home", originalUserHome); } public String getHomeDir() { return homeDir; } public String getTestDataDir() { return testDataDir; } public String getTestDir() { return testDir; } public String getBuildDir() { return buildDir; } public String getPackageSubDir() { return packageSubDir; } }jdepend-2.9.1/test/jdepend/framework/ExampleInterface.java0000644000000000000000000000062110236624040022272 0ustar rootrootpackage jdepend.framework; import java.math.BigDecimal; /** * @author Mike Clark * @author Clarkware Consulting, Inc. */ public interface ExampleInterface { public void a(); public java.util.Vector b(String[] s, java.text.NumberFormat nf); public void c(BigDecimal bd, byte[] b) throws java.rmi.RemoteException; public java.io.File[] d() throws java.io.IOException; }jdepend-2.9.1/test/data/0000755000000000000000000000000010236624040013517 5ustar rootrootjdepend-2.9.1/test/data/test.jar0000644000000000000000000000711010236624040015173 0ustar rootrootPK*X1 META-INF/PKPK*X1META-INF/MANIFEST.MFMLK-. K-*ϳR03r.JM,IMu *h8*8(x%irrPKΞ\FFPK X1jdepend/PK "X1jdepend/framework/PKX1,jdepend/framework/ExampleAbstractClass.classRMo1}YM?~m{D!**5('q؏q W ?MBR=7OGPG;xP'vc > /qӲxX^XW[m쓤# + ȗCFI –*=OAՈ69qjωND4 dI(F#/pj^-G/,ё0jz->ѩ_D`]Ub ;ngU T$Zvmwgp]'N'#OYnuZJ3ʚSX2[sʸ%B8{" 6f6%f:Rޥ#6sއ3g5pOPã K|zRw7v,Xajeyn6[Er1KX ҜXm!2^2So Yb;p*,+cwAbLlMK`;|ڵ ^PK+} PKX1>jdepend/framework/ExampleConcreteClass$ExampleInnerClass.classMK@Mcccjބ"ƣRJt[MIS?~<Ql,xCYaww>>fl9(; Ժ!MIXN!G9ԉtSBPf'ޓNFOVI[4;ѐ]r>P|-!gJ(a_E6& ܅,G%MT]n/+3W[k,磊UzXAAE RW1@f`9&y6R-d˪ 6^!XϬ,q4=@wQH)i֗O؀PKȀ:YPKX1,jdepend/framework/ExampleConcreteClass.classTrE=ˮqd$F"  X!*S*W4ZuVf5F_x< 0GQe%*;鞑?㉇ŗ3x!\lxk\lx,0K?v@`QtZU,uG~i&< P?W;Fa{*N"FI  $wyT沈Ik$q*(H鉕4G$\ʂ#&9 lVm~-hRܧIڗVu;*IjXuq @.X/2"Jvȁ_ ˨֭z3\nmkVodRi i)NJwCԦ fwZI4P": ~X{!?hzPj=H&N;*|Ԣ@m7U_V@)/sOpdߕ_EuW`~P渹.^j  -њ͒-ʘ@"os~GB~,2)P_&}S-zn\".=72ůc^x4G k]Upa.u/:bStZϜ8|,b YƧj--N6 ˿Ls%ppYN0s6ޮ5[x9K.rT>~k, wsD\۴7IPuǴ9|b>12k߀PKYjLsPKX1(jdepend/framework/ExampleInterface.class]PMO1"_ x{?`&DHH$p]Xn76-(4o23i?>tq- ^M%~Jf*_ȱw:_[S$h+Ro]SRpIRmTO{՞fL/ιc&ʁ(aخ\J!p/)2\ԭn3*(ɹS^{W%PhHzDvlg3GcS~X\sq g_PKlPKX1+jdepend/framework/ExamplePackageClass.classON@K! Q>DcAeHα~ wN>vvv4~}bcG6^\.)X`i:gDyQT-jĠ{ѭyVfSgK55v%ީ^W<'%@l{';Oeۚ%R#,,/Yu8=Kv nzet ð%&[ޕPK* ?PK*X1 META-INF/PK*X1Ξ\FF=META-INF/MANIFEST.MFPK X1jdepend/PK "X1jdepend/framework/PKX1+} ,jdepend/framework/ExampleAbstractClass.classPKX1Ȁ:Y>~jdepend/framework/ExampleConcreteClass$ExampleInnerClass.classPKX1YjLs,$jdepend/framework/ExampleConcreteClass.classPKX1l(jdepend/framework/ExampleInterface.classPKX1* ?+1 jdepend/framework/ExamplePackageClass.classPK p jdepend-2.9.1/test/data/test.zip0000644000000000000000000000711010236624040015221 0ustar rootrootPK.X1 META-INF/PKPK.X1META-INF/MANIFEST.MFMLK-. K-*ϳR03r.JM,IMu *h8*8(x%irrPKΞ\FFPK X1jdepend/PK "X1jdepend/framework/PKX1,jdepend/framework/ExampleAbstractClass.classRMo1}YM?~m{D!**5('q؏q W ?MBR=7OGPG;xP'vc > /qӲxX^XW[m쓤# + ȗCFI –*=OAՈ69qjωND4 dI(F#/pj^-G/,ё0jz->ѩ_D`]Ub ;ngU T$Zvmwgp]'N'#OYnuZJ3ʚSX2[sʸ%B8{" 6f6%f:Rޥ#6sއ3g5pOPã K|zRw7v,Xajeyn6[Er1KX ҜXm!2^2So Yb;p*,+cwAbLlMK`;|ڵ ^PK+} PKX1>jdepend/framework/ExampleConcreteClass$ExampleInnerClass.classMK@Mcccjބ"ƣRJt[MIS?~<Ql,xCYaww>>fl9(; Ժ!MIXN!G9ԉtSBPf'ޓNFOVI[4;ѐ]r>P|-!gJ(a_E6& ܅,G%MT]n/+3W[k,磊UzXAAE RW1@f`9&y6R-d˪ 6^!XϬ,q4=@wQH)i֗O؀PKȀ:YPKX1,jdepend/framework/ExampleConcreteClass.classTrE=ˮqd$F"  X!*S*W4ZuVf5F_x< 0GQe%*;鞑?㉇ŗ3x!\lxk\lx,0K?v@`QtZU,uG~i&< P?W;Fa{*N"FI  $wyT沈Ik$q*(H鉕4G$\ʂ#&9 lVm~-hRܧIڗVu;*IjXuq @.X/2"Jvȁ_ ˨֭z3\nmkVodRi i)NJwCԦ fwZI4P": ~X{!?hzPj=H&N;*|Ԣ@m7U_V@)/sOpdߕ_EuW`~P渹.^j  -њ͒-ʘ@"os~GB~,2)P_&}S-zn\".=72ůc^x4G k]Upa.u/:bStZϜ8|,b YƧj--N6 ˿Ls%ppYN0s6ޮ5[x9K.rT>~k, wsD\۴7IPuǴ9|b>12k߀PKYjLsPKX1(jdepend/framework/ExampleInterface.class]PMO1"_ x{?`&DHH$p]Xn76-(4o23i?>tq- ^M%~Jf*_ȱw:_[S$h+Ro]SRpIRmTO{՞fL/ιc&ʁ(aخ\J!p/)2\ԭn3*(ɹS^{W%PhHzDvlg3GcS~X\sq g_PKlPKX1+jdepend/framework/ExamplePackageClass.classON@K! Q>DcAeHα~ wN>vvv4~}bcG6^\.)X`i:gDyQT-jĠ{ѭyVfSgK55v%ީ^W<'%@l{';Oeۚ%R#,,/Yu8=Kv nzet ð%&[ޕPK* ?PK.X1 META-INF/PK.X1Ξ\FF=META-INF/MANIFEST.MFPK X1jdepend/PK "X1jdepend/framework/PKX1+} ,jdepend/framework/ExampleAbstractClass.classPKX1Ȁ:Y>~jdepend/framework/ExampleConcreteClass$ExampleInnerClass.classPKX1YjLs,$jdepend/framework/ExampleConcreteClass.classPKX1l(jdepend/framework/ExampleInterface.classPKX1* ?+1 jdepend/framework/ExamplePackageClass.classPK p jdepend-2.9.1/test/data/jdepend.properties0000644000000000000000000000024110236624040017243 0ustar rootrootignore.java=java.*,javax.* ignore.sun=sun.*,com.sun.* ignore.tests=com.xyz.tests.* analyzeInnerClasses=false com.xyz.a.neverchanges=0 com.xyz.b.neverchanges=0 jdepend-2.9.1/src/0000755000000000000000000000000010236624040012416 5ustar rootrootjdepend-2.9.1/src/jdepend/0000755000000000000000000000000010236624040014027 5ustar rootrootjdepend-2.9.1/src/jdepend/textui/0000755000000000000000000000000010236624040015351 5ustar rootrootjdepend-2.9.1/src/jdepend/textui/JDepend.java0000644000000000000000000003513410236624040017533 0ustar rootrootpackage jdepend.textui; import java.io.*; import java.util.*; import java.text.NumberFormat; import jdepend.framework.JavaClass; import jdepend.framework.JavaPackage; import jdepend.framework.PackageComparator; import jdepend.framework.PackageFilter; /** * The JDepend class analyzes directories of Java class files, * generates metrics for each Java package, and reports the metrics in a textual * format. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JDepend { private jdepend.framework.JDepend analyzer; private PrintWriter writer; protected NumberFormat formatter; /** * Constructs a JDepend instance using standard output. */ public JDepend() { this(new PrintWriter(System.out)); } /** * Constructs a JDepend instance with the specified writer. * * @param writer Writer. */ public JDepend(PrintWriter writer) { analyzer = new jdepend.framework.JDepend(); formatter = NumberFormat.getInstance(); formatter.setMaximumFractionDigits(2); setWriter(writer); } /** * Sets the output writer. * * @param writer Output writer. */ public void setWriter(PrintWriter writer) { this.writer = writer; } protected PrintWriter getWriter() { return writer; } /** * Sets the package filter. * * @param filter Package filter. */ public void setFilter(PackageFilter filter) { analyzer.setFilter(filter); } /** * Sets the comma-separated list of components. */ public void setComponents(String components) { analyzer.setComponents(components); } /** * Adds the specified directory name to the collection of directories to be * analyzed. * * @param name Directory name. * @throws IOException If the directory does not exist. */ public void addDirectory(String name) throws IOException { analyzer.addDirectory(name); } /** * Determines whether inner classes are analyzed. * * @param b true to analyze inner classes; false * otherwise. */ public void analyzeInnerClasses(boolean b) { analyzer.analyzeInnerClasses(b); } /** * Analyzes the registered directories, generates metrics for each Java * package, and reports the metrics. */ public void analyze() { printHeader(); Collection packages = analyzer.analyze(); ArrayList packageList = new ArrayList(packages); Collections.sort(packageList, new PackageComparator(PackageComparator .byName())); printPackages(packageList); printCycles(packageList); printSummary(packageList); printFooter(); getWriter().flush(); } protected void printPackages(Collection packages) { printPackagesHeader(); Iterator i = packages.iterator(); while (i.hasNext()) { printPackage((JavaPackage) i.next()); } printPackagesFooter(); } protected void printPackage(JavaPackage jPackage) { printPackageHeader(jPackage); if (jPackage.getClasses().size() == 0) { printNoStats(); printPackageFooter(jPackage); return; } printStatistics(jPackage); printSectionBreak(); printAbstractClasses(jPackage); printSectionBreak(); printConcreteClasses(jPackage); printSectionBreak(); printEfferents(jPackage); printSectionBreak(); printAfferents(jPackage); printPackageFooter(jPackage); } protected void printAbstractClasses(JavaPackage jPackage) { printAbstractClassesHeader(); ArrayList members = new ArrayList(jPackage.getClasses()); Collections.sort(members, new JavaClass.ClassComparator()); Iterator memberIter = members.iterator(); while (memberIter.hasNext()) { JavaClass jClass = (JavaClass) memberIter.next(); if (jClass.isAbstract()) { printClassName(jClass); } } printAbstractClassesFooter(); } protected void printConcreteClasses(JavaPackage jPackage) { printConcreteClassesHeader(); ArrayList members = new ArrayList(jPackage.getClasses()); Collections.sort(members, new JavaClass.ClassComparator()); Iterator memberIter = members.iterator(); while (memberIter.hasNext()) { JavaClass concrete = (JavaClass) memberIter.next(); if (!concrete.isAbstract()) { printClassName(concrete); } } printConcreteClassesFooter(); } protected void printEfferents(JavaPackage jPackage) { printEfferentsHeader(); ArrayList efferents = new ArrayList(jPackage.getEfferents()); Collections.sort(efferents, new PackageComparator(PackageComparator .byName())); Iterator efferentIter = efferents.iterator(); while (efferentIter.hasNext()) { JavaPackage efferent = (JavaPackage) efferentIter.next(); printPackageName(efferent); } if (efferents.size() == 0) { printEfferentsError(); } printEfferentsFooter(); } protected void printAfferents(JavaPackage jPackage) { printAfferentsHeader(); ArrayList afferents = new ArrayList(jPackage.getAfferents()); Collections.sort(afferents, new PackageComparator(PackageComparator .byName())); Iterator afferentIter = afferents.iterator(); while (afferentIter.hasNext()) { JavaPackage afferent = (JavaPackage) afferentIter.next(); printPackageName(afferent); } if (afferents.size() == 0) { printAfferentsError(); } printAfferentsFooter(); } protected void printCycles(Collection packages) { printCyclesHeader(); Iterator i = packages.iterator(); while (i.hasNext()) { printCycle((JavaPackage) i.next()); } printCyclesFooter(); } protected void printCycle(JavaPackage jPackage) { List list = new ArrayList(); jPackage.collectCycle(list); if (!jPackage.containsCycle()) { return; } JavaPackage cyclePackage = (JavaPackage) list.get(list.size() - 1); String cyclePackageName = cyclePackage.getName(); int i = 0; Iterator pkgIter = list.iterator(); while (pkgIter.hasNext()) { i++; JavaPackage pkg = (JavaPackage) pkgIter.next(); if (i == 1) { printCycleHeader(pkg); } else { if (pkg.getName().equals(cyclePackageName)) { printCycleTarget(pkg); } else { printCycleContributor(pkg); } } } printCycleFooter(); } protected void printHeader() { // do nothing } protected void printFooter() { // do nothing } protected void printPackagesHeader() { // do nothing } protected void printPackagesFooter() { // do nothing } protected void printNoStats() { getWriter().println( "No stats available: package referenced, but not analyzed."); } protected void printPackageHeader(JavaPackage jPackage) { getWriter().println( "\n--------------------------------------------------"); getWriter().println("- Package: " + jPackage.getName()); getWriter().println( "--------------------------------------------------"); } protected void printPackageFooter(JavaPackage jPackage) { // do nothing } protected void printStatistics(JavaPackage jPackage) { getWriter().println("\nStats:"); getWriter().println( tab() + "Total Classes: " + jPackage.getClassCount()); getWriter() .println( tab() + "Concrete Classes: " + jPackage.getConcreteClassCount()); getWriter() .println( tab() + "Abstract Classes: " + jPackage.getAbstractClassCount()); getWriter().println(""); getWriter().println(tab() + "Ca: " + jPackage.afferentCoupling()); getWriter().println(tab() + "Ce: " + jPackage.efferentCoupling()); getWriter().println(""); getWriter().println( tab() + "A: " + toFormattedString(jPackage.abstractness())); getWriter().println( tab() + "I: " + toFormattedString(jPackage.instability())); getWriter().println( tab() + "D: " + toFormattedString(jPackage.distance())); } protected void printClassName(JavaClass jClass) { getWriter().println(tab() + jClass.getName()); } protected void printPackageName(JavaPackage jPackage) { getWriter().println(tab() + jPackage.getName()); } protected void printAbstractClassesHeader() { getWriter().println("Abstract Classes:"); } protected void printAbstractClassesFooter() { // do nothing } protected void printConcreteClassesHeader() { getWriter().println("Concrete Classes:"); } protected void printConcreteClassesFooter() { // do nothing } protected void printEfferentsHeader() { getWriter().println("Depends Upon:"); } protected void printEfferentsFooter() { // do nothing } protected void printEfferentsError() { getWriter().println(tab() + "Not dependent on any packages."); } protected void printAfferentsHeader() { getWriter().println("Used By:"); } protected void printAfferentsFooter() { // do nothing } protected void printAfferentsError() { getWriter().println(tab() + "Not used by any packages."); } protected void printCyclesHeader() { printSectionBreak(); getWriter().println( "\n--------------------------------------------------"); getWriter().println("- Package Dependency Cycles:"); getWriter().println( "--------------------------------------------------\n"); } protected void printCyclesFooter() { // do nothing } protected void printCycleHeader(JavaPackage jPackage) { getWriter().println(jPackage.getName()); getWriter().println(tab() + "|"); } protected void printCycleTarget(JavaPackage jPackage) { getWriter().println(tab() + "|-> " + jPackage.getName()); } protected void printCycleContributor(JavaPackage jPackage) { getWriter().println(tab() + "| " + jPackage.getName()); } protected void printCycleFooter() { printSectionBreak(); } protected void printSummary(Collection packages) { getWriter().println( "\n--------------------------------------------------"); getWriter().println("- Summary:"); getWriter().println( "--------------------------------------------------\n"); getWriter() .println( "Name, Class Count, Abstract Class Count, Ca, Ce, A, I, D, V:\n"); Iterator i = packages.iterator(); while (i.hasNext()) { JavaPackage jPackage = (JavaPackage) i.next(); getWriter().print(jPackage.getName() + ","); getWriter().print(jPackage.getClassCount() + ","); getWriter().print(jPackage.getAbstractClassCount() + ","); getWriter().print(jPackage.afferentCoupling() + ","); getWriter().print(jPackage.efferentCoupling() + ","); getWriter().print(toFormattedString(jPackage.abstractness()) + ","); getWriter().print(toFormattedString(jPackage.instability()) + ","); getWriter().print(toFormattedString(jPackage.distance()) + ","); getWriter().println(jPackage.getVolatility()); } } protected void printSectionBreak() { getWriter().println(""); } protected String toFormattedString(float f) { return formatter.format(f); } protected String tab() { return " "; } protected String tab(int n) { StringBuffer s = new StringBuffer(); for (int i = 0; i < n; i++) { s.append(tab()); } return s.toString(); } protected void usage(String message) { if (message != null) { System.err.println("\n" + message); } String baseUsage = "\nJDepend "; System.err.println(""); System.err.println("usage: "); System.err.println(baseUsage + "[-components ]" + " [-file ] " + "[directory2 [directory 3] ...]"); System.exit(1); } protected void instanceMain(String[] args) { if (args.length < 1) { usage("Must specify at least one directory."); } int directoryCount = 0; for (int i = 0; i < args.length; i++) { if (args[i].startsWith("-")) { if (args[i].equalsIgnoreCase("-file")) { if (args.length <= i + 1) { usage("Output file name not specified."); } try { setWriter(new PrintWriter(new OutputStreamWriter( new FileOutputStream(args[++i]), "UTF8"))); } catch (IOException ioe) { usage(ioe.getMessage()); } } else if (args[i].equalsIgnoreCase("-components")) { if (args.length <= i + 1) { usage("Components not specified."); } setComponents(args[++i]); } else { usage("Invalid argument: " + args[i]); } } else { try { addDirectory(args[i]); directoryCount++; } catch (IOException ioe) { usage("Directory does not exist: " + args[i]); } } } if (directoryCount == 0) { usage("Must specify at least one directory."); } analyze(); } public static void main(String args[]) { new JDepend().instanceMain(args); } } jdepend-2.9.1/src/jdepend/xmlui/0000755000000000000000000000000010236624040015165 5ustar rootrootjdepend-2.9.1/src/jdepend/xmlui/JDepend.java0000644000000000000000000001315210236624040017343 0ustar rootrootpackage jdepend.xmlui; import java.io.*; import java.util.*; import java.text.NumberFormat; import jdepend.framework.JavaClass; import jdepend.framework.JavaPackage; /** * The JDepend class analyzes directories of Java class files, * generates metrics for each Java package, and reports the metrics in an XML * format. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JDepend extends jdepend.textui.JDepend { /** * Constructs a JDepend instance using standard output. */ public JDepend() { this(new PrintWriter(System.out)); } /** * Constructs a JDepend instance with the specified writer. * * @param writer Writer. */ public JDepend(PrintWriter writer) { super(writer); formatter = NumberFormat.getInstance(Locale.ENGLISH); formatter.setMaximumFractionDigits(2); } protected void printHeader() { getWriter().println(""); getWriter().println(""); } protected void printFooter() { getWriter().println(""); } protected void printPackagesHeader() { getWriter().println(tab() + ""); } protected void printPackagesFooter() { getWriter().println(tab() + ""); } protected void printPackageHeader(JavaPackage jPackage) { printSectionBreak(); getWriter().println( tab(2) + ""); } protected void printPackageFooter(JavaPackage jPackage) { getWriter().println(tab(2) + ""); } protected void printNoStats() { getWriter().println( tab(3) + "No stats available: " + "package referenced, but not analyzed."); } protected void printStatistics(JavaPackage jPackage) { getWriter().println(tab(3) + ""); getWriter().println( tab(4) + "" + jPackage.getClassCount() + ""); getWriter().println( tab(4) + "" + jPackage.getConcreteClassCount() + ""); getWriter().println( tab(4) + "" + jPackage.getAbstractClassCount() + ""); getWriter().println( tab(4) + "" + jPackage.afferentCoupling() + ""); getWriter().println( tab(4) + "" + jPackage.efferentCoupling() + ""); getWriter().println( tab(4) + "" + toFormattedString(jPackage.abstractness()) + ""); getWriter().println( tab(4) + "" + toFormattedString(jPackage.instability()) + ""); getWriter().println( tab(4) + "" + toFormattedString(jPackage.distance()) + ""); getWriter().println(tab(4) + "" + jPackage.getVolatility() + ""); getWriter().println(tab(3) + ""); } protected void printClassName(JavaClass jClass) { getWriter().println( tab(4) + ""); getWriter().println(tab(5) + jClass.getName()); getWriter().println(tab(4) + ""); } protected void printPackageName(JavaPackage jPackage) { getWriter().println( tab(4) + "" + jPackage.getName() + ""); } protected void printAbstractClassesHeader() { getWriter().println(tab(3) + ""); } protected void printAbstractClassesFooter() { getWriter().println(tab(3) + ""); } protected void printConcreteClassesHeader() { getWriter().println(tab(3) + ""); } protected void printConcreteClassesFooter() { getWriter().println(tab(3) + ""); } protected void printEfferentsHeader() { getWriter().println(tab(3) + ""); } protected void printEfferentsFooter() { getWriter().println(tab(3) + ""); } protected void printEfferentsError() { // do nothing } protected void printAfferentsHeader() { getWriter().println(tab(3) + ""); } protected void printAfferentsFooter() { getWriter().println(tab(3) + ""); } protected void printAfferentsError() { // do nothing } protected void printCyclesHeader() { printSectionBreak(); getWriter().println(tab() + ""); } protected void printCyclesFooter() { getWriter().println(tab() + ""); } protected void printCycleHeader(JavaPackage jPackage) { getWriter().println( tab(2) + ""); } protected void printCycleFooter() { getWriter().println(tab(2) + ""); printSectionBreak(); } protected void printCycleTarget(JavaPackage jPackage) { printCycleContributor(jPackage); } protected void printCycleContributor(JavaPackage jPackage) { getWriter().println( tab(3) + "" + jPackage.getName() + ""); } protected void printSummary(Collection packages) { // do nothing } /** * Main. */ public static void main(String args[]) { new JDepend().instanceMain(args); } }jdepend-2.9.1/src/jdepend/framework/0000755000000000000000000000000010236624040016024 5ustar rootrootjdepend-2.9.1/src/jdepend/framework/AbstractParser.java0000644000000000000000000000324210236624040021610 0ustar rootrootpackage jdepend.framework; import java.io.*; import java.util.*; /** * The AbstractParser class is the base class * for classes capable of parsing files to create a * JavaClass instance. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public abstract class AbstractParser { private ArrayList parseListeners; private PackageFilter filter; public static boolean DEBUG = false; public AbstractParser() { this(new PackageFilter()); } public AbstractParser(PackageFilter filter) { setFilter(filter); parseListeners = new ArrayList(); } public void addParseListener(ParserListener listener) { parseListeners.add(listener); } /** * Registered parser listeners are informed that the resulting * JavaClass was parsed. */ public abstract JavaClass parse(InputStream is) throws IOException; /** * Informs registered parser listeners that the specified * JavaClass was parsed. * * @param jClass Parsed Java class. */ protected void onParsedJavaClass(JavaClass jClass) { for (Iterator i = parseListeners.iterator(); i.hasNext();) { ((ParserListener) i.next()).onParsedJavaClass(jClass); } } protected PackageFilter getFilter() { if (filter == null) { setFilter(new PackageFilter()); } return filter; } protected void setFilter(PackageFilter filter) { this.filter = filter; } protected void debug(String message) { if (DEBUG) { System.err.println(message); } } }jdepend-2.9.1/src/jdepend/framework/PackageComparator.java0000644000000000000000000000203410236624040022251 0ustar rootrootpackage jdepend.framework; import java.util.Comparator; /** * The PackageComparator class is a Comparator * used to compare two JavaPackage instances for order using a * sorting strategy. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class PackageComparator implements Comparator { private PackageComparator byWhat; private static PackageComparator byName; static { byName = new PackageComparator(); } public static PackageComparator byName() { return byName; } private PackageComparator() { } public PackageComparator(PackageComparator byWhat) { this.byWhat = byWhat; } public PackageComparator byWhat() { return byWhat; } public int compare(Object p1, Object p2) { JavaPackage a = (JavaPackage) p1; JavaPackage b = (JavaPackage) p2; if (byWhat() == byName()) { return a.getName().compareTo(b.getName()); } return 0; } }jdepend-2.9.1/src/jdepend/framework/JDepend.java0000644000000000000000000002300210236624040020175 0ustar rootrootpackage jdepend.framework; import java.io.IOException; import java.util.*; /** * The JDepend class analyzes directories of Java class files * and generates the following metrics for each Java package. *

*

    *
  • Afferent Coupling (Ca) *

    * The number of packages that depend upon the classes within the analyzed * package. *

    *
  • *
  • Efferent Coupling (Ce) *

    * The number of packages that the classes in the analyzed package depend upon. *

    *
  • *
  • Abstractness (A) *

    * The ratio of the number of abstract classes (and interfaces) in the analyzed * package to the total number of classes in the analyzed package. *

    *

    * The range for this metric is 0 to 1, with A=0 indicating a completely * concrete package and A=1 indicating a completely abstract package. *

    *
  • *
  • Instability (I) *

    * The ratio of efferent coupling (Ce) to total coupling (Ce + Ca) such that I = * Ce / (Ce + Ca). *

    *

    * The range for this metric is 0 to 1, with I=0 indicating a completely stable * package and I=1 indicating a completely instable package. *

    *
  • *
  • Distance from the Main Sequence (D) *

    * The perpendicular distance of a package from the idealized line A + I = 1. A * package coincident with the main sequence is optimally balanced with respect * to its abstractness and stability. Ideal packages are either completely * abstract and stable (x=0, y=1) or completely concrete and instable (x=1, * y=0). *

    *

    * The range for this metric is 0 to 1, with D=0 indicating a package that is * coincident with the main sequence and D=1 indicating a package that is as far * from the main sequence as possible. *

    *
  • *
  • Package Dependency Cycle *

    * Package dependency cycles are reported along with the paths of packages * participating in package dependency cycles. *

    *
  • *
*

* These metrics are hereafter referred to as the "Martin Metrics", as they are * credited to Robert Martin (Object Mentor Inc.) and referenced in the book * "Designing Object Oriented C++ Applications using the Booch Method", by * Robert C. Martin, Prentice Hall, 1995. *

*

* Example API use: *

*

* *
 * JDepend jdepend = new JDepend();
 * jdepend.addDirectory("/path/to/classes");
 * Collection packages = jdepend.analyze();
 * 
 * Iterator i = packages.iterator();
 * while (i.hasNext()) {
 *     JavaPackage jPackage = (JavaPackage) i.next();
 *     String name = jPackage.getName();
 *     int Ca = jPackage.afferentCoupling();
 *     int Ce = jPackage.efferentCoupling();
 *     float A = jPackage.abstractness();
 *     float I = jPackage.instability();
 *     float D = jPackage.distance();
 *     boolean b = jPackage.containsCycle();
 * }
 * 
* *
*

*

* This class is the data model used by the jdepend.textui.JDepend * and jdepend.swingui.JDepend views. *

* * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JDepend { private HashMap packages; private FileManager fileManager; private PackageFilter filter; private ClassFileParser parser; private JavaClassBuilder builder; private Collection components; public JDepend() { this(new PackageFilter()); } public JDepend(PackageFilter filter) { setFilter(filter); this.packages = new HashMap(); this.fileManager = new FileManager(); this.parser = new ClassFileParser(filter); this.builder = new JavaClassBuilder(parser, fileManager); PropertyConfigurator config = new PropertyConfigurator(); addPackages(config.getConfiguredPackages()); analyzeInnerClasses(config.getAnalyzeInnerClasses()); } /** * Analyzes the registered directories and returns the collection of * analyzed packages. * * @return Collection of analyzed packages. */ public Collection analyze() { Collection classes = builder.build(); for (Iterator i = classes.iterator(); i.hasNext();) { analyzeClass((JavaClass)i.next()); } return getPackages(); } /** * Adds the specified directory name to the collection of directories to be * analyzed. * * @param name Directory name. * @throws IOException If the directory is invalid. */ public void addDirectory(String name) throws IOException { fileManager.addDirectory(name); } /** * Sets the list of components. * * @param components Comma-separated list of components. */ public void setComponents(String components) { this.components = new ArrayList(); StringTokenizer st = new StringTokenizer(components, ","); while (st.hasMoreTokens()) { String component = st.nextToken(); this.components.add(component); } } /** * Determines whether inner classes are analyzed. * * @param b true to analyze inner classes; * false otherwise. */ public void analyzeInnerClasses(boolean b) { fileManager.acceptInnerClasses(b); } /** * Returns the collection of analyzed packages. * * @return Collection of analyzed packages. */ public Collection getPackages() { return packages.values(); } /** * Returns the analyzed package of the specified name. * * @param name Package name. * @return Package, or null if the package was not analyzed. */ public JavaPackage getPackage(String name) { return (JavaPackage)packages.get(name); } /** * Returns the number of analyzed Java packages. * * @return Number of Java packages. */ public int countPackages() { return getPackages().size(); } /** * Returns the number of registered Java classes to be analyzed. * * @return Number of classes. */ public int countClasses() { return builder.countClasses(); } /** * Indicates whether the packages contain one or more dependency cycles. * * @return true if one or more dependency cycles exist. */ public boolean containsCycles() { for (Iterator i = getPackages().iterator(); i.hasNext();) { JavaPackage jPackage = (JavaPackage)i.next(); if (jPackage.containsCycle()) { return true; } } return false; } /** * Indicates whether the analyzed packages match the specified * dependency constraint. * * @return true if the packages match the dependency * constraint */ public boolean dependencyMatch(DependencyConstraint constraint) { return constraint.match(getPackages()); } /** * Registers the specified parser listener. * * @param listener Parser listener. */ public void addParseListener(ParserListener listener) { parser.addParseListener(listener); } /** * Adds the specified Java package name to the collection of analyzed * packages. * * @param name Java package name. * @return Added Java package. */ public JavaPackage addPackage(String name) { name = toComponent(name); JavaPackage pkg = (JavaPackage)packages.get(name); if (pkg == null) { pkg = new JavaPackage(name); addPackage(pkg); } return pkg; } private String toComponent(String packageName) { if (components != null) { for (Iterator i = components.iterator(); i.hasNext();) { String component = (String)i.next(); if (packageName.startsWith(component + ".")) { return component; } } } return packageName; } /** * Adds the specified collection of packages to the collection * of analyzed packages. * * @param packages Collection of packages. */ public void addPackages(Collection packages) { for (Iterator i = packages.iterator(); i.hasNext();) { JavaPackage pkg = (JavaPackage)i.next(); addPackage(pkg); } } /** * Adds the specified Java package to the collection of * analyzed packages. * * @param pkg Java package. */ public void addPackage(JavaPackage pkg) { if (!packages.containsValue(pkg)) { packages.put(pkg.getName(), pkg); } } public PackageFilter getFilter() { if (filter == null) { filter = new PackageFilter(); } return filter; } public void setFilter(PackageFilter filter) { if (parser != null) { parser.setFilter(filter); } this.filter = filter; } private void analyzeClass(JavaClass clazz) { String packageName = clazz.getPackageName(); if (!getFilter().accept(packageName)) { return; } JavaPackage clazzPackage = addPackage(packageName); clazzPackage.addClass(clazz); Collection imports = clazz.getImportedPackages(); for (Iterator i = imports.iterator(); i.hasNext();) { JavaPackage importedPackage = (JavaPackage)i.next(); importedPackage = addPackage(importedPackage.getName()); clazzPackage.dependsUpon(importedPackage); } } } jdepend-2.9.1/src/jdepend/framework/ParserListener.java0000644000000000000000000000116310236624040021632 0ustar rootrootpackage jdepend.framework; /** * The ParserListener interface defines a listener * notified upon the completion of parsing events. *

* Implementers of this interface register for notification using * the JDepend.addParseListener() method. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public interface ParserListener { /** * Called whenever a Java class file is parsed into the specified * JavaClass instance. * * @param parsedClass Parsed Java class. */ public void onParsedJavaClass(JavaClass parsedClass); }jdepend-2.9.1/src/jdepend/framework/ClassFileParser.java0000644000000000000000000004534210236624040021721 0ustar rootrootpackage jdepend.framework; import java.io.*; import java.util.*; /** * The ClassFileParser class is responsible for * parsing a Java class file to create a JavaClass * instance. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class ClassFileParser extends AbstractParser { public static final int JAVA_MAGIC = 0xCAFEBABE; public static final int CONSTANT_UTF8 = 1; public static final int CONSTANT_UNICODE = 2; public static final int CONSTANT_INTEGER = 3; public static final int CONSTANT_FLOAT = 4; public static final int CONSTANT_LONG = 5; public static final int CONSTANT_DOUBLE = 6; public static final int CONSTANT_CLASS = 7; public static final int CONSTANT_STRING = 8; public static final int CONSTANT_FIELD = 9; public static final int CONSTANT_METHOD = 10; public static final int CONSTANT_INTERFACEMETHOD = 11; public static final int CONSTANT_NAMEANDTYPE = 12; public static final char CLASS_DESCRIPTOR = 'L'; public static final int ACC_INTERFACE = 0x200; public static final int ACC_ABSTRACT = 0x400; private String fileName; private String className; private String superClassName; private String interfaceNames[]; private boolean isAbstract; private JavaClass jClass; private Constant[] constantPool; private FieldOrMethodInfo[] fields; private FieldOrMethodInfo[] methods; private AttributeInfo[] attributes; private DataInputStream in; public ClassFileParser() { this(new PackageFilter()); } public ClassFileParser(PackageFilter filter) { super(filter); reset(); } private void reset() { className = null; superClassName = null; interfaceNames = new String[0]; isAbstract = false; jClass = null; constantPool = new Constant[1]; fields = new FieldOrMethodInfo[0]; methods = new FieldOrMethodInfo[0]; attributes = new AttributeInfo[0]; } /** * Registered parser listeners are informed that the resulting * JavaClass was parsed. */ public JavaClass parse(File classFile) throws IOException { this.fileName = classFile.getCanonicalPath(); debug("\nParsing " + fileName + "..."); FileInputStream in = null; try { in = new FileInputStream(classFile); return parse(in); } finally { if (in != null) { try { in.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } } } public JavaClass parse(InputStream is) throws IOException { reset(); jClass = new JavaClass("Unknown"); in = new DataInputStream(is); int magic = parseMagic(); int minorVersion = parseMinorVersion(); int majorVersion = parseMajorVersion(); constantPool = parseConstantPool(); parseAccessFlags(); className = parseClassName(); superClassName = parseSuperClassName(); interfaceNames = parseInterfaces(); fields = parseFields(); methods = parseMethods(); parseAttributes(); addClassConstantReferences(); onParsedJavaClass(jClass); return jClass; } private int parseMagic() throws IOException { int magic = in.readInt(); if (magic != JAVA_MAGIC) { throw new IOException("Invalid class file: " + fileName); } return magic; } private int parseMinorVersion() throws IOException { return in.readUnsignedShort(); } private int parseMajorVersion() throws IOException { return in.readUnsignedShort(); } private Constant[] parseConstantPool() throws IOException { int constantPoolSize = in.readUnsignedShort(); Constant[] pool = new Constant[constantPoolSize]; for (int i = 1; i < constantPoolSize; i++) { Constant constant = parseNextConstant(); pool[i] = constant; // // 8-byte constants use two constant pool entries // if (constant.getTag() == CONSTANT_DOUBLE || constant.getTag() == CONSTANT_LONG) { i++; } } return pool; } private void parseAccessFlags() throws IOException { int accessFlags = in.readUnsignedShort(); boolean isAbstract = ((accessFlags & ACC_ABSTRACT) != 0); boolean isInterface = ((accessFlags & ACC_INTERFACE) != 0); this.isAbstract = isAbstract || isInterface; jClass.isAbstract(this.isAbstract); debug("Parser: abstract = " + this.isAbstract); } private String parseClassName() throws IOException { int entryIndex = in.readUnsignedShort(); String className = getClassConstantName(entryIndex); jClass.setName(className); jClass.setPackageName(getPackageName(className)); debug("Parser: class name = " + className); debug("Parser: package name = " + getPackageName(className)); return className; } private String parseSuperClassName() throws IOException { int entryIndex = in.readUnsignedShort(); String superClassName = getClassConstantName(entryIndex); addImport(getPackageName(superClassName)); debug("Parser: super class name = " + superClassName); return superClassName; } private String[] parseInterfaces() throws IOException { int interfacesCount = in.readUnsignedShort(); String[] interfaceNames = new String[interfacesCount]; for (int i = 0; i < interfacesCount; i++) { int entryIndex = in.readUnsignedShort(); interfaceNames[i] = getClassConstantName(entryIndex); addImport(getPackageName(interfaceNames[i])); debug("Parser: interface = " + interfaceNames[i]); } return interfaceNames; } private FieldOrMethodInfo[] parseFields() throws IOException { int fieldsCount = in.readUnsignedShort(); FieldOrMethodInfo[] fields = new FieldOrMethodInfo[fieldsCount]; for (int i = 0; i < fieldsCount; i++) { fields[i] = parseFieldOrMethodInfo(); String descriptor = toUTF8(fields[i].getDescriptorIndex()); debug("Parser: field descriptor = " + descriptor); String[] types = descriptorToTypes(descriptor); for (int t = 0; t < types.length; t++) { addImport(getPackageName(types[t])); debug("Parser: field type = " + types[t]); } } return fields; } private FieldOrMethodInfo[] parseMethods() throws IOException { int methodsCount = in.readUnsignedShort(); FieldOrMethodInfo[] methods = new FieldOrMethodInfo[methodsCount]; for (int i = 0; i < methodsCount; i++) { methods[i] = parseFieldOrMethodInfo(); String descriptor = toUTF8(methods[i].getDescriptorIndex()); debug("Parser: method descriptor = " + descriptor); String[] types = descriptorToTypes(descriptor); for (int t = 0; t < types.length; t++) { if (types[t].length() > 0) { addImport(getPackageName(types[t])); debug("Parser: method type = " + types[t]); } } } return methods; } private Constant parseNextConstant() throws IOException { Constant result; byte tag = in.readByte(); switch (tag) { case (ClassFileParser.CONSTANT_CLASS): case (ClassFileParser.CONSTANT_STRING): result = new Constant(tag, in.readUnsignedShort()); break; case (ClassFileParser.CONSTANT_FIELD): case (ClassFileParser.CONSTANT_METHOD): case (ClassFileParser.CONSTANT_INTERFACEMETHOD): case (ClassFileParser.CONSTANT_NAMEANDTYPE): result = new Constant(tag, in.readUnsignedShort(), in .readUnsignedShort()); break; case (ClassFileParser.CONSTANT_INTEGER): result = new Constant(tag, new Integer(in.readInt())); break; case (ClassFileParser.CONSTANT_FLOAT): result = new Constant(tag, new Float(in.readFloat())); break; case (ClassFileParser.CONSTANT_LONG): result = new Constant(tag, new Long(in.readLong())); break; case (ClassFileParser.CONSTANT_DOUBLE): result = new Constant(tag, new Double(in.readDouble())); break; case (ClassFileParser.CONSTANT_UTF8): result = new Constant(tag, in.readUTF()); break; default: throw new IOException("Unknown constant: " + tag); } return result; } private FieldOrMethodInfo parseFieldOrMethodInfo() throws IOException { FieldOrMethodInfo result = new FieldOrMethodInfo( in.readUnsignedShort(), in.readUnsignedShort(), in .readUnsignedShort()); int attributesCount = in.readUnsignedShort(); for (int a = 0; a < attributesCount; a++) { parseAttribute(); } return result; } private void parseAttributes() throws IOException { int attributesCount = in.readUnsignedShort(); attributes = new AttributeInfo[attributesCount]; for (int i = 0; i < attributesCount; i++) { attributes[i] = parseAttribute(); // Section 4.7.7 of VM Spec - Class File Format if (attributes[i].getName() != null) { if (attributes[i].getName().equals("SourceFile")) { byte[] b = attributes[i].getValue(); int b0 = b[0] < 0 ? b[0] + 256 : b[0]; int b1 = b[1] < 0 ? b[1] + 256 : b[1]; int pe = b0 * 256 + b1; String descriptor = toUTF8(pe); jClass.setSourceFile(descriptor); } } } } private AttributeInfo parseAttribute() throws IOException { AttributeInfo result = new AttributeInfo(); int nameIndex = in.readUnsignedShort(); if (nameIndex != -1) { result.setName(toUTF8(nameIndex)); } int attributeLength = in.readInt(); byte[] value = new byte[attributeLength]; for (int b = 0; b < attributeLength; b++) { value[b] = in.readByte(); } result.setValue(value); return result; } private Constant getConstantPoolEntry(int entryIndex) throws IOException { if (entryIndex < 0 || entryIndex >= constantPool.length) { throw new IOException("Illegal constant pool index : " + entryIndex); } return constantPool[entryIndex]; } private void addClassConstantReferences() throws IOException { for (int j = 1; j < constantPool.length; j++) { if (constantPool[j].getTag() == CONSTANT_CLASS) { String name = toUTF8(constantPool[j].getNameIndex()); addImport(getPackageName(name)); debug("Parser: class type = " + slashesToDots(name)); } if (constantPool[j].getTag() == CONSTANT_DOUBLE || constantPool[j].getTag() == CONSTANT_LONG) { j++; } } } private String getClassConstantName(int entryIndex) throws IOException { Constant entry = getConstantPoolEntry(entryIndex); if (entry == null) { return ""; } return slashesToDots(toUTF8(entry.getNameIndex())); } private String toUTF8(int entryIndex) throws IOException { Constant entry = getConstantPoolEntry(entryIndex); if (entry.getTag() == CONSTANT_UTF8) { return (String) entry.getValue(); } throw new IOException("Constant pool entry is not a UTF8 type: " + entryIndex); } private void addImport(String importPackage) { if ((importPackage != null) && (getFilter().accept(importPackage))) { jClass.addImportedPackage(new JavaPackage(importPackage)); } } private String slashesToDots(String s) { return s.replace('/', '.'); } private String getPackageName(String s) { if ((s.length() > 0) && (s.charAt(0) == '[')) { String types[] = descriptorToTypes(s); if (types.length == 0) { return null; // primitives } s = types[0]; } s = slashesToDots(s); int index = s.lastIndexOf("."); if (index > 0) { return s.substring(0, index); } return "Default"; } private String[] descriptorToTypes(String descriptor) { int typesCount = 0; for (int index = 0; index < descriptor.length(); index++) { if (descriptor.charAt(index) == ';') { typesCount++; } } String types[] = new String[typesCount]; int typeIndex = 0; for (int index = 0; index < descriptor.length(); index++) { int startIndex = descriptor.indexOf(CLASS_DESCRIPTOR, index); if (startIndex < 0) { break; } index = descriptor.indexOf(';', startIndex + 1); types[typeIndex++] = descriptor.substring(startIndex + 1, index); } return types; } class Constant { private byte _tag; private int _nameIndex; private int _typeIndex; private Object _value; Constant(byte tag, int nameIndex) { this(tag, nameIndex, -1); } Constant(byte tag, Object value) { this(tag, -1, -1); _value = value; } Constant(byte tag, int nameIndex, int typeIndex) { _tag = tag; _nameIndex = nameIndex; _typeIndex = typeIndex; _value = null; } byte getTag() { return _tag; } int getNameIndex() { return _nameIndex; } int getTypeIndex() { return _typeIndex; } Object getValue() { return _value; } public String toString() { StringBuffer s = new StringBuffer(""); s.append("tag: " + getTag()); if (getNameIndex() > -1) { s.append(" nameIndex: " + getNameIndex()); } if (getTypeIndex() > -1) { s.append(" typeIndex: " + getTypeIndex()); } if (getValue() != null) { s.append(" value: " + getValue()); } return s.toString(); } } class FieldOrMethodInfo { private int _accessFlags; private int _nameIndex; private int _descriptorIndex; FieldOrMethodInfo(int accessFlags, int nameIndex, int descriptorIndex) { _accessFlags = accessFlags; _nameIndex = nameIndex; _descriptorIndex = descriptorIndex; } int accessFlags() { return _accessFlags; } int getNameIndex() { return _nameIndex; } int getDescriptorIndex() { return _descriptorIndex; } public String toString() { StringBuffer s = new StringBuffer(""); try { s.append("\n name (#" + getNameIndex() + ") = " + toUTF8(getNameIndex())); s.append("\n signature (#" + getDescriptorIndex() + ") = " + toUTF8(getDescriptorIndex())); String[] types = descriptorToTypes(toUTF8(getDescriptorIndex())); for (int t = 0; t < types.length; t++) { s.append("\n type = " + types[t]); } } catch (Exception e) { e.printStackTrace(); } return s.toString(); } } class AttributeInfo { private String name; private byte[] value; public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setValue(byte[] value) { this.value = value; } public byte[] getValue() { return this.value; } } /** * Returns a string representation of this object. * * @return String representation. */ public String toString() { StringBuffer s = new StringBuffer(); try { s.append("\n" + className + ":\n"); s.append("\nConstants:\n"); for (int i = 1; i < constantPool.length; i++) { Constant entry = getConstantPoolEntry(i); s.append(" " + i + ". " + entry.toString() + "\n"); if (entry.getTag() == CONSTANT_DOUBLE || entry.getTag() == CONSTANT_LONG) { i++; } } s.append("\nClass Name: " + className + "\n"); s.append("Super Name: " + superClassName + "\n\n"); s.append(interfaceNames.length + " interfaces\n"); for (int i = 0; i < interfaceNames.length; i++) { s.append(" " + interfaceNames[i] + "\n"); } s.append("\n" + fields.length + " fields\n"); for (int i = 0; i < fields.length; i++) { s.append(fields[i].toString() + "\n"); } s.append("\n" + methods.length + " methods\n"); for (int i = 0; i < methods.length; i++) { s.append(methods[i].toString() + "\n"); } s.append("\nDependencies:\n"); Iterator imports = jClass.getImportedPackages().iterator(); while (imports.hasNext()) { JavaPackage jPackage = (JavaPackage) imports.next(); s.append(" " + jPackage.getName() + "\n"); } } catch (Exception e) { e.printStackTrace(); } return s.toString(); } /** * Test main. */ public static void main(String args[]) { try { ClassFileParser.DEBUG = true; if (args.length <= 0) { System.err.println("usage: ClassFileParser "); System.exit(0); } ClassFileParser parser = new ClassFileParser(); parser.parse(new File(args[0])); System.err.println(parser.toString()); } catch (Exception e) { System.err.println(e.getMessage()); } } } jdepend-2.9.1/src/jdepend/framework/DependencyConstraint.java0000644000000000000000000001061110236624040023011 0ustar rootrootpackage jdepend.framework; import java.util.*; import jdepend.framework.JavaPackage; /** * The DependencyConstraint class is a constraint that tests * whether two package-dependency graphs are equivalent. *

* This class is useful for writing package dependency assertions (e.g. JUnit). * For example, the following JUnit test will ensure that the 'ejb' and 'web' * packages only depend upon the 'util' package, and no others: *

*

* *
 * 
 * public void testDependencyConstraint() {
 * 
 *     JDepend jdepend = new JDepend();
 *     jdepend.addDirectory("/path/to/classes");
 *     Collection analyzedPackages = jdepend.analyze();
 * 
 *     DependencyConstraint constraint = new DependencyConstraint();
 * 
 *     JavaPackage ejb = constraint.addPackage("com.xyz.ejb");
 *     JavaPackage web = constraint.addPackage("com.xyz.web");
 *     JavaPackage util = constraint.addPackage("com.xyz.util");
 * 
 *     ejb.dependsUpon(util);
 *     web.dependsUpon(util);
 * 
 *     assertEquals("Dependency mismatch", true, constraint
 *             .match(analyzedPackages));
 * }
 * 
* *
*

* * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class DependencyConstraint { private HashMap packages; public DependencyConstraint() { packages = new HashMap(); } public JavaPackage addPackage(String packageName) { JavaPackage jPackage = (JavaPackage) packages.get(packageName); if (jPackage == null) { jPackage = new JavaPackage(packageName); addPackage(jPackage); } return jPackage; } public void addPackage(JavaPackage jPackage) { if (!packages.containsValue(jPackage)) { packages.put(jPackage.getName(), jPackage); } } public Collection getPackages() { return packages.values(); } /** * Indicates whether the specified packages match the * packages in this constraint. * * @return true if the packages match this constraint */ public boolean match(Collection expectedPackages) { if (packages.size() == expectedPackages.size()) { for (Iterator i = expectedPackages.iterator(); i.hasNext();) { Object next = i.next(); if (next instanceof JavaPackage) { JavaPackage nextPackage = (JavaPackage) next; if (!matchPackage(nextPackage)) { return false; } } else { break; } return true; } } return false; } private boolean matchPackage(JavaPackage expectedPackage) { JavaPackage actualPackage = (JavaPackage) packages.get(expectedPackage .getName()); if (actualPackage != null) { if (equalsDependencies(actualPackage, expectedPackage)) { return true; } } return false; } private boolean equalsDependencies(JavaPackage a, JavaPackage b) { return equalsAfferents(a, b) && equalsEfferents(a, b); } private boolean equalsAfferents(JavaPackage a, JavaPackage b) { if (a.equals(b)) { Collection otherAfferents = b.getAfferents(); if (a.getAfferents().size() == otherAfferents.size()) { for (Iterator i = a.getAfferents().iterator(); i.hasNext();) { JavaPackage afferent = (JavaPackage)i.next(); if (!otherAfferents.contains(afferent)) { return false; } } return true; } } return false; } private boolean equalsEfferents(JavaPackage a, JavaPackage b) { if (a.equals(b)) { Collection otherEfferents = b.getEfferents(); if (a.getEfferents().size() == otherEfferents.size()) { for (Iterator i = a.getEfferents().iterator(); i.hasNext();) { JavaPackage efferent = (JavaPackage)i.next(); if (!otherEfferents.contains(efferent)) { return false; } } return true; } } return false; } }jdepend-2.9.1/src/jdepend/framework/JavaPackage.java0000644000000000000000000001440110236624040021024 0ustar rootrootpackage jdepend.framework; import java.util.*; /** * The JavaPackage class represents a Java package. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JavaPackage { private String name; private int volatility; private HashSet classes; private List afferents; private List efferents; public JavaPackage(String name) { this(name, 1); } public JavaPackage(String name, int volatility) { this.name = name; setVolatility(volatility); classes = new HashSet(); afferents = new ArrayList(); efferents = new ArrayList(); } public String getName() { return name; } /** * @return The package's volatility (0-1). */ public int getVolatility() { return volatility; } /** * @param v Volatility (0-1). */ public void setVolatility(int v) { volatility = v; } public boolean containsCycle() { return collectCycle(new ArrayList()); } /** * Collects the packages participating in the first package dependency cycle * detected which originates from this package. * * @param list Collecting object to be populated with the list of * JavaPackage instances in a cycle. * @return true if a cycle exist; false * otherwise. */ public boolean collectCycle(List list) { if (list.contains(this)) { list.add(this); return true; } list.add(this); for (Iterator i = getEfferents().iterator(); i.hasNext();) { JavaPackage efferent = (JavaPackage)i.next(); if (efferent.collectCycle(list)) { return true; } } list.remove(this); return false; } /** * Collects all the packages participating in a package dependency cycle * which originates from this package. *

* This is a more exhaustive search than that employed by * collectCycle. * * @param list Collecting object to be populated with the list of * JavaPackage instances in a cycle. * @return true if a cycle exist; false * otherwise. */ public boolean collectAllCycles(List list) { if (list.contains(this)) { list.add(this); return true; } list.add(this); boolean containsCycle = false; for (Iterator i = getEfferents().iterator(); i.hasNext();) { JavaPackage efferent = (JavaPackage)i.next(); if (efferent.collectAllCycles(list)) { containsCycle = true; } } if (containsCycle) { return true; } list.remove(this); return false; } public void addClass(JavaClass clazz) { classes.add(clazz); } public Collection getClasses() { return classes; } public int getClassCount() { return classes.size(); } public int getAbstractClassCount() { int count = 0; for (Iterator i = classes.iterator(); i.hasNext();) { JavaClass clazz = (JavaClass)i.next(); if (clazz.isAbstract()) { count++; } } return count; } public int getConcreteClassCount() { int count = 0; for (Iterator i = classes.iterator(); i.hasNext();) { JavaClass clazz = (JavaClass)i.next(); if (!clazz.isAbstract()) { count++; } } return count; } /** * Adds the specified Java package as an efferent of this package * and adds this package as an afferent of it. * * @param imported Java package. */ public void dependsUpon(JavaPackage imported) { addEfferent(imported); imported.addAfferent(this); } /** * Adds the specified Java package as an afferent of this package. * * @param jPackage Java package. */ public void addAfferent(JavaPackage jPackage) { if (!jPackage.getName().equals(getName())) { if (!afferents.contains(jPackage)) { afferents.add(jPackage); } } } public Collection getAfferents() { return afferents; } public void setAfferents(Collection afferents) { this.afferents = new ArrayList(afferents); } public void addEfferent(JavaPackage jPackage) { if (!jPackage.getName().equals(getName())) { if (!efferents.contains(jPackage)) { efferents.add(jPackage); } } } public Collection getEfferents() { return efferents; } public void setEfferents(Collection efferents) { this.efferents = new ArrayList(efferents); } /** * @return The afferent coupling (Ca) of this package. */ public int afferentCoupling() { return afferents.size(); } /** * @return The efferent coupling (Ce) of this package. */ public int efferentCoupling() { return efferents.size(); } /** * @return Instability (0-1). */ public float instability() { float totalCoupling = (float) efferentCoupling() + (float) afferentCoupling(); if (totalCoupling > 0) { return efferentCoupling()/totalCoupling; } return 0; } /** * @return The package's abstractness (0-1). */ public float abstractness() { if (getClassCount() > 0) { return (float) getAbstractClassCount() / (float) getClassCount(); } return 0; } /** * @return The package's distance from the main sequence (D). */ public float distance() { float d = Math.abs(abstractness() + instability() - 1); return d * volatility; } public boolean equals(Object other) { if (other instanceof JavaPackage) { JavaPackage otherPackage = (JavaPackage) other; return otherPackage.getName().equals(getName()); } return false; } public int hashCode() { return getName().hashCode(); } } jdepend-2.9.1/src/jdepend/framework/FileManager.java0000644000000000000000000000633210236624040021045 0ustar rootrootpackage jdepend.framework; import java.io.*; import java.util.*; /** * The FileManager class is responsible for extracting * Java class files (.class files) from a collection of * registered directories. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class FileManager { private ArrayList directories; private boolean acceptInnerClasses; public FileManager() { directories = new ArrayList(); acceptInnerClasses = true; } /** * Determines whether inner classes should be collected. * * @param b true to collect inner classes; * false otherwise. */ public void acceptInnerClasses(boolean b) { acceptInnerClasses = b; } public void addDirectory(String name) throws IOException { File directory = new File(name); if (directory.isDirectory() || acceptJarFile(directory)) { directories.add(directory); } else { throw new IOException("Invalid directory or JAR file: " + name); } } public boolean acceptFile(File file) { return acceptClassFile(file) || acceptJarFile(file); } public boolean acceptClassFile(File file) { if (!file.isFile()) { return false; } return acceptClassFileName(file.getName()); } public boolean acceptClassFileName(String name) { if (!acceptInnerClasses) { if (name.toLowerCase().indexOf("$") > 0) { return false; } } if (!name.toLowerCase().endsWith(".class")) { return false; } return true; } public boolean acceptJarFile(File file) { return isJar(file) || isZip(file) || isWar(file); } public Collection extractFiles() { Collection files = new ArrayList(); for (Iterator i = directories.iterator(); i.hasNext();) { File directory = (File)i.next(); collectFiles(directory, files); } return files; } private void collectFiles(File directory, Collection files) { if (directory.isFile()) { addFile(directory, files); } else { String[] directoryFiles = directory.list(); for (int i = 0; i < directoryFiles.length; i++) { File file = new File(directory, directoryFiles[i]); if (acceptFile(file)) { addFile(file, files); } else if (file.isDirectory()) { collectFiles(file, files); } } } } private void addFile(File f, Collection files) { if (!files.contains(f)) { files.add(f); } } private boolean isWar(File file) { return existsWithExtension(file, ".war"); } private boolean isZip(File file) { return existsWithExtension(file, ".zip"); } private boolean isJar(File file) { return existsWithExtension(file, ".jar"); } private boolean existsWithExtension(File file, String extension) { return file.isFile() && file.getName().toLowerCase().endsWith(extension); } }jdepend-2.9.1/src/jdepend/framework/JavaClassBuilder.java0000644000000000000000000000727010236624040022053 0ustar rootrootpackage jdepend.framework; import java.io.*; import java.util.*; import java.util.jar.*; import java.util.zip.*; /** * The JavaClassBuilder builds JavaClass * instances from .class, .jar, .war, or .zip files. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JavaClassBuilder { private AbstractParser parser; private FileManager fileManager; public JavaClassBuilder() { this(new ClassFileParser(), new FileManager()); } public JavaClassBuilder(FileManager fm) { this(new ClassFileParser(), fm); } public JavaClassBuilder(AbstractParser parser, FileManager fm) { this.parser = parser; this.fileManager = fm; } public int countClasses() { AbstractParser counter = new AbstractParser() { public JavaClass parse(InputStream is) { return new JavaClass(""); } }; JavaClassBuilder builder = new JavaClassBuilder(counter, fileManager); Collection classes = builder.build(); return classes.size(); } /** * Builds the JavaClass instances. * * @return Collection of JavaClass instances. */ public Collection build() { Collection classes = new ArrayList(); for (Iterator i = fileManager.extractFiles().iterator(); i.hasNext();) { File nextFile = (File)i.next(); try { classes.addAll(buildClasses(nextFile)); } catch (IOException ioe) { System.err.println("\n" + ioe.getMessage()); } } return classes; } /** * Builds the JavaClass instances from the * specified file. * * @param file Class or Jar file. * @return Collection of JavaClass instances. */ public Collection buildClasses(File file) throws IOException { if (fileManager.acceptClassFile(file)) { FileInputStream fis = null; try { fis = new FileInputStream(file); JavaClass parsedClass = parser.parse(fis); Collection javaClasses = new ArrayList(); javaClasses.add(parsedClass); return javaClasses; } finally { if (fis != null) { fis.close(); } } } else if (fileManager.acceptJarFile(file)) { JarFile jarFile = new JarFile(file); Collection result = buildClasses(jarFile); jarFile.close(); return result; } else { throw new IOException("File is not a valid " + ".class, .jar, .war, or .zip file: " + file.getPath()); } } /** * Builds the JavaClass instances from the specified * jar, war, or zip file. * * @param file Jar, war, or zip file. * @return Collection of JavaClass instances. */ public Collection buildClasses(JarFile file) throws IOException { Collection javaClasses = new ArrayList(); Enumeration entries = file.entries(); while (entries.hasMoreElements()) { ZipEntry e = (ZipEntry) entries.nextElement(); if (fileManager.acceptClassFileName(e.getName())) { InputStream is = null; try { is = file.getInputStream(e); JavaClass jc = parser.parse(is); javaClasses.add(jc); } finally { is.close(); } } } return javaClasses; } } jdepend-2.9.1/src/jdepend/framework/PackageFilter.java0000644000000000000000000000532610236624040021376 0ustar rootrootpackage jdepend.framework; import java.io.*; import java.util.*; /** * The PackageFilter class is used to filter imported * package names. *

* The default filter contains any packages declared in the * jdepend.properties file, if such a file exists * either in the user's home directory or somewhere in the classpath. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class PackageFilter { private Collection filtered; /** * Constructs a PackageFilter instance containing * the filters specified in the jdepend.properties file, * if it exists. */ public PackageFilter() { this(new ArrayList()); PropertyConfigurator config = new PropertyConfigurator(); addPackages(config.getFilteredPackages()); } /** * Constructs a PackageFilter instance containing * the filters contained in the specified file. * * @param f Property file. */ public PackageFilter(File f) { this(new ArrayList()); PropertyConfigurator config = new PropertyConfigurator(f); addPackages(config.getFilteredPackages()); } /** * Constructs a PackageFilter instance with the * specified collection of package names to filter. * * @param packageNames Package names to filter. */ public PackageFilter(Collection packageNames) { filtered = new ArrayList(); addPackages(packageNames); } /** * Returns the collection of filtered package names. * * @return Filtered package names. */ public Collection getFilters() { return filtered; } /** * Indicates whether the specified package name passes this package filter. * * @param packageName Package name. * @return true if the package name should be included; * false otherwise. */ public boolean accept(String packageName) { for (Iterator i = getFilters().iterator(); i.hasNext();) { String nameToFilter = (String)i.next(); if (packageName.startsWith(nameToFilter)) { return false; } } return true; } public void addPackages(Collection packageNames) { for (Iterator i = packageNames.iterator(); i.hasNext();) { addPackage((String)i.next()); } } public void addPackage(String packageName) { if (packageName.endsWith("*")) { packageName = packageName.substring(0, packageName.length() - 1); } if (packageName.length() > 0) { getFilters().add(packageName); } } } jdepend-2.9.1/src/jdepend/framework/JavaClass.java0000644000000000000000000000377410236624040020551 0ustar rootrootpackage jdepend.framework; import java.util.*; /** * The JavaClass class represents a Java * class or interface. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JavaClass { private String className; private String packageName; private boolean isAbstract; private HashMap imports; private String sourceFile; public JavaClass(String name) { className = name; packageName = "default"; isAbstract = false; imports = new HashMap(); sourceFile = "Unknown"; } public void setName(String name) { className = name; } public String getName() { return className; } public void setPackageName(String name) { packageName = name; } public String getPackageName() { return packageName; } public void setSourceFile(String name) { sourceFile = name; } public String getSourceFile() { return sourceFile; } public Collection getImportedPackages() { return imports.values(); } public void addImportedPackage(JavaPackage jPackage) { if (!jPackage.getName().equals(getPackageName())) { imports.put(jPackage.getName(), jPackage); } } public boolean isAbstract() { return isAbstract; } public void isAbstract(boolean isAbstract) { this.isAbstract = isAbstract; } public boolean equals(Object other) { if (other instanceof JavaClass) { JavaClass otherClass = (JavaClass) other; return otherClass.getName().equals(getName()); } return false; } public int hashCode() { return getName().hashCode(); } public static class ClassComparator implements Comparator { public int compare(Object a, Object b) { JavaClass c1 = (JavaClass) a; JavaClass c2 = (JavaClass) b; return c1.getName().compareTo(c2.getName()); } } } jdepend-2.9.1/src/jdepend/framework/PropertyConfigurator.java0000644000000000000000000000741310236624040023103 0ustar rootrootpackage jdepend.framework; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Properties; import java.util.StringTokenizer; /** * The PropertyConfigurator class contains configuration * information contained in the jdepend.properties file, * if such a file exists either in the user's home directory or somewhere * in the classpath. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class PropertyConfigurator { private Properties properties; public static final String DEFAULT_PROPERTY_FILE = "jdepend.properties"; /** * Constructs a PropertyConfigurator instance * containing the properties specified in the file * jdepend.properties, if it exists. */ public PropertyConfigurator() { this(getDefaultPropertyFile()); } /** * Constructs a PropertyConfigurator instance * with the specified property set. * * @param p Property set. */ public PropertyConfigurator(Properties p) { this.properties = p; } /** * Constructs a PropertyConfigurator instance * with the specified property file. * * @param f Property file. */ public PropertyConfigurator(File f) { this(loadProperties(f)); } public Collection getFilteredPackages() { Collection packages = new ArrayList(); Enumeration e = properties.propertyNames(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); if (key.startsWith("ignore")) { String path = properties.getProperty(key); StringTokenizer st = new StringTokenizer(path, ","); while (st.hasMoreTokens()) { String name = (String) st.nextToken(); name = name.trim(); packages.add(name); } } } return packages; } public Collection getConfiguredPackages() { Collection packages = new ArrayList(); Enumeration e = properties.propertyNames(); while (e.hasMoreElements()) { String key = (String)e.nextElement(); if (!key.startsWith("ignore") && (!key.equals("analyzeInnerClasses"))) { String v = properties.getProperty(key); packages.add(new JavaPackage(key, new Integer(v).intValue())); } } return packages; } public boolean getAnalyzeInnerClasses() { String key = "analyzeInnerClasses"; if (properties.containsKey(key)) { String value = properties.getProperty(key); return new Boolean(value).booleanValue(); } return true; } public static File getDefaultPropertyFile() { String home = System.getProperty("user.home"); return new File(home, DEFAULT_PROPERTY_FILE); } public static Properties loadProperties(File file) { Properties p = new Properties(); InputStream is = null; try { is = new FileInputStream(file); } catch (Exception e) { is = PropertyConfigurator.class.getResourceAsStream("/" + DEFAULT_PROPERTY_FILE); } try { if (is != null) { p.load(is); } } catch (IOException ignore) { } finally { try { if (is != null) { is.close(); } } catch (IOException ignore) { } } return p; } }jdepend-2.9.1/src/jdepend/swingui/0000755000000000000000000000000010236624040015514 5ustar rootrootjdepend-2.9.1/src/jdepend/swingui/DependTree.java0000644000000000000000000000574410236624040020410 0ustar rootrootpackage jdepend.swingui; import java.awt.*; import javax.swing.*; import javax.swing.tree.*; import javax.swing.event.*; import jdepend.framework.JavaPackage; /** * The DependTree class defines the graphical tree for displaying * the packages and their hierarchical dependencies. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class DependTree extends JPanel implements TreeSelectionListener { private JTree tree; private DependTreeModel model; /** * Constructs a DependTree with an empty tree model. */ public DependTree() { this(new DependTreeModel(new AfferentNode(null, new JavaPackage("")))); } /** * Constructs a DependTree with the specified tree model. * * @param model Depend tree model. */ public DependTree(DependTreeModel model) { setBorder(BorderFactory.createTitledBorder(model.getRoot().toString())); setModel(model); setLayout(new BorderLayout()); JScrollPane pane = createScrollPane(); add(pane, "Center"); } /** * Sets the tree model. * * @param model Tree model. */ public void setModel(DependTreeModel model) { this.model = model; setBorder(BorderFactory.createTitledBorder(model.getRoot().toString())); getTree().setModel(this.model); } /** * Returns the tree model. * * @return Tree model. */ public DependTreeModel getModel() { return (DependTreeModel) getTree().getModel(); } /** * Registers the specified listener with this tree. * * @param l Tree selection listener. */ public void addTreeSelectionListener(TreeSelectionListener l) { getTree().addTreeSelectionListener(l); } /** * Callback method triggered whenever the value of the tree selection * changes. * * @param te Event that characterizes the change. */ public void valueChanged(TreeSelectionEvent te) { TreePath path = te.getNewLeadSelectionPath(); if (path != null) { Object o = path.getLastPathComponent(); } } /** * Creates and returns a scroll pane. * * @return Scroll pane. */ private JScrollPane createScrollPane() { JScrollPane pane = new JScrollPane(getTree()); return pane; } /** * Creates and returns a peered tree. * * @return Tree. */ private JTree createTree() { JTree tree = new JTree(); tree.setShowsRootHandles(false); tree.setFont(new Font("Dialog", Font.PLAIN, 12)); tree.addTreeSelectionListener(this); tree.setRootVisible(false); tree.setLargeModel(true); return tree; } /* * Returns the peered tree. @return A non-null tree. */ private JTree getTree() { if (tree == null) { tree = createTree(); } return tree; } } jdepend-2.9.1/src/jdepend/swingui/PackageNode.java0000644000000000000000000001152610236624040020525 0ustar rootrootpackage jdepend.swingui; import java.text.NumberFormat; import java.util.*; import jdepend.framework.*; /** * The PackageNode class defines the default behavior for tree * nodes representing Java packages. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public abstract class PackageNode { private PackageNode parent; private JavaPackage jPackage; private ArrayList children; private static NumberFormat formatter; static { formatter = NumberFormat.getInstance(); formatter.setMaximumFractionDigits(2); } /** * Constructs a PackageNode with the specified package and * its collection of dependent packages. * * @param parent Parent package node. * @param jPackage Java package. */ public PackageNode(PackageNode parent, JavaPackage jPackage) { this.parent = parent; this.jPackage = jPackage; children = null; } /** * Returns the Java package represented in this node. * * @return Java package. */ public JavaPackage getPackage() { return jPackage; } /** * Returns the parent of this package node. * * @return Parent package node. */ public PackageNode getParent() { return parent; } /** * Indicates whether this node is a leaf node. * * @return true if this node is a leaf; false * otherwise. */ public boolean isLeaf() { if (getCoupledPackages().size() > 0) { return false; } return true; } /** * Creates and returns a PackageNode with the specified * parent node and Java package. * * @param parent Parent package node. * @param jPackage Java package. * @return A non-null PackageNodetrue to display the package; false * otherwise. */ public boolean isChild(JavaPackage jPackage) { return true; } /** * Returns the child package nodes of this node. * * @return Collection of child package nodes. */ public ArrayList getChildren() { if (children == null) { children = new ArrayList(); ArrayList packages = new ArrayList(getCoupledPackages()); Collections.sort(packages, new PackageComparator(PackageComparator .byName())); Iterator i = packages.iterator(); while (i.hasNext()) { JavaPackage jPackage = (JavaPackage) i.next(); if (isChild(jPackage)) { PackageNode childNode = makeNode(this, jPackage); children.add(childNode); } } } return children; } /** * Returns the string representation of this node's metrics. * * @return Metrics string. */ public String toMetricsString() { StringBuffer label = new StringBuffer(); label.append(getPackage().getName()); label.append(" ("); label.append("CC: " + getPackage().getConcreteClassCount() + " "); label.append("AC: " + getPackage().getAbstractClassCount() + " "); label.append("Ca: " + getPackage().afferentCoupling() + " "); label.append("Ce: " + getPackage().efferentCoupling() + " "); label.append("A: " + format(getPackage().abstractness()) + " "); label.append("I: " + format(getPackage().instability()) + " "); label.append("D: " + format(getPackage().distance()) + " "); label.append("V: " + getPackage().getVolatility()); if (getPackage().containsCycle()) { label.append(" Cyclic"); } label.append(")"); return label.toString(); } /** * Returns the string representation of this node in it's current tree * context. * * @return Node label. */ public String toString() { if (getParent().getParent() == null) { return toMetricsString(); } return getPackage().getName(); } /* * Returns the specified number in a displayable format. @param number * Number to format. @return Formatted number. */ private static String format(float f) { return formatter.format(f); } } jdepend-2.9.1/src/jdepend/swingui/JDepend.java0000644000000000000000000003477510236624040017710 0ustar rootrootpackage jdepend.swingui; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; import javax.swing.tree.*; import jdepend.framework.JavaClass; import jdepend.framework.JavaPackage; import jdepend.framework.PackageComparator; import jdepend.framework.PackageFilter; import jdepend.framework.ParserListener; /** * The JDepend class analyzes directories of Java class files, * generates metrics for each Java package, and reports the metrics in a Swing * tree. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class JDepend implements ParserListener { private jdepend.framework.JDepend analyzer; private JFrame frame; private StatusPanel statusPanel; private JTextField statusField; private JProgressBar progressBar; private DependTree afferentTree; private DependTree efferentTree; private Hashtable resourceStrings; private Hashtable actions; private static Font BOLD_FONT = new Font("dialog", Font.BOLD, 12); /** * Constructs a JDepend instance. */ public JDepend() { analyzer = new jdepend.framework.JDepend(); analyzer.addParseListener(this); // // Force the cross platform L&F. // try { UIManager.setLookAndFeel(UIManager .getCrossPlatformLookAndFeelClassName()); //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } // // Install the resource string table. // resourceStrings = new Hashtable(); resourceStrings.put("menubar", "File"); resourceStrings.put("File", "About Exit"); // // Install the action table. // actions = new Hashtable(); actions.put("About", new AboutAction()); actions.put("Exit", new ExitAction()); } /** * Adds the specified directory name to the collection of directories to be * analyzed. * * @param name Directory name. * @throws IOException If the directory does not exist. */ public void addDirectory(String name) throws IOException { analyzer.addDirectory(name); } /** * Sets the package filter. * * @param filter Package filter. */ public void setFilter(PackageFilter filter) { analyzer.setFilter(filter); } /** * Sets the comma-separated list of components. */ public void setComponents(String components) { analyzer.setComponents(components); } /** * Analyzes the registered directories, generates metrics for each Java * package, and reports the metrics in a graphical format. */ public void analyze() { display(); startProgressMonitor(analyzer.countClasses()); ArrayList packages = new ArrayList(analyzer.analyze()); Collections.sort(packages, new PackageComparator(PackageComparator .byName())); stopProgressMonitor(); updateTree(packages); } /** * Called whenever a Java source file is parsed into the specified * JavaClass instance. * * @param jClass Parsed Java class. */ public void onParsedJavaClass(final JavaClass jClass) { SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressBar().setValue(getProgressBar().getValue() + 1); } }); } private void display() { frame = createUI(); frame.setVisible(true); } private void updateTree(ArrayList packages) { JavaPackage jPackage = new JavaPackage("root"); jPackage.setAfferents(packages); jPackage.setEfferents(packages); AfferentNode ah = new AfferentNode(null, jPackage); getAfferentTree().setModel(new DependTreeModel(ah)); EfferentNode eh = new EfferentNode(null, jPackage); getEfferentTree().setModel(new DependTreeModel(eh)); } private void startProgressMonitor(final int maxValue) { SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressBar().setMinimum(0); getProgressBar().setMaximum(maxValue); getStatusPanel().setStatusComponent(getProgressBar()); } }); } private void stopProgressMonitor() { SwingUtilities.invokeLater(new Runnable() { public void run() { getStatusPanel().setStatusComponent(getStatusField()); int classCount = analyzer.countClasses(); int packageCount = analyzer.countPackages(); showStatusMessage("Analyzed " + packageCount + " packages (" + classCount + " classes)."); } }); } private JFrame createUI() { JFrame frame = createFrame("JDepend"); JMenuBar menuBar = createMenubar(); frame.setJMenuBar(menuBar); JPanel treePanel = createTreePanel(); StatusPanel statusPanel = getStatusPanel(); frame.getContentPane().add("Center", treePanel); frame.getContentPane().add("South", statusPanel); frame.pack(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int width = 700; int height = 500; int x = (screenSize.width - width) / 2; int y = (screenSize.height - height) / 2; frame.setBounds(x, y, width, height); frame.setSize(width, height); return frame; } private JFrame createFrame(String title) { JFrame frame = new JFrame(title); frame.getContentPane().setLayout(new BorderLayout()); frame.setBackground(SystemColor.control); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { new ExitAction().actionPerformed(null); } }); return frame; } private JPanel createTreePanel() { JPanel panel = new JPanel(); panel.setLayout(new GridLayout(2, 1)); panel.add(getEfferentTree()); panel.add(getAfferentTree()); /* * panel.setLayout(new GridLayout(1,1)); JSplitPane splitPane = new * JSplitPane(JSplitPane.VERTICAL_SPLIT); * splitPane.setOneTouchExpandable(true); * splitPane.setTopComponent(getEfferentTree()); * splitPane.setBottomComponent(getAfferentTree()); * panel.add(splitPane); */ return panel; } private StatusPanel createStatusPanel() { StatusPanel panel = new StatusPanel(); panel.setStatusComponent(getStatusField()); return panel; } private JProgressBar createProgressBar() { JProgressBar bar = new JProgressBar(); bar.setStringPainted(true); return bar; } private JTextField createStatusField() { JTextField statusField = new JTextField(); statusField.setFont(BOLD_FONT); statusField.setEditable(false); statusField.setForeground(Color.black); statusField.setBorder(BorderFactory .createBevelBorder(BevelBorder.LOWERED)); Insets insets = new Insets(5, 5, 5, 5); statusField.setMargin(insets); return statusField; } private JMenuBar createMenubar() { JMenuBar menuBar = new JMenuBar(); String[] menuKeys = tokenize((String) resourceStrings.get("menubar")); for (int i = 0; i < menuKeys.length; i++) { JMenu m = createMenu(menuKeys[i]); if (m != null) { menuBar.add(m); } } return menuBar; } private JMenu createMenu(String key) { String[] itemKeys = tokenize((String) resourceStrings.get(key)); JMenu menu = new JMenu(key); for (int i = 0; i < itemKeys.length; i++) { if (itemKeys[i].equals("-")) { menu.addSeparator(); } else { JMenuItem mi = createMenuItem(itemKeys[i]); menu.add(mi); } } char mnemonic = key.charAt(0); menu.setMnemonic(mnemonic); return menu; } private JMenuItem createMenuItem(String key) { JMenuItem mi = new JMenuItem(key); char mnemonic = key.charAt(0); mi.setMnemonic(mnemonic); char accelerator = key.charAt(0); mi.setAccelerator(KeyStroke.getKeyStroke(accelerator, java.awt.Event.CTRL_MASK)); String actionString = key; mi.setActionCommand(actionString); Action a = getActionForCommand(actionString); if (a != null) { mi.addActionListener(a); mi.setEnabled(a.isEnabled()); } else { mi.setEnabled(false); } return mi; } private void showStatusMessage(final String message) { getStatusField().setFont(BOLD_FONT); getStatusField().setForeground(Color.black); getStatusField().setText(" " + message); } private void showStatusError(final String message) { getStatusField().setFont(BOLD_FONT); getStatusField().setForeground(Color.red); getStatusField().setText(" " + message); } private DependTree getAfferentTree() { if (afferentTree == null) { afferentTree = new DependTree(); afferentTree.addTreeSelectionListener(new TreeListener()); } return afferentTree; } private DependTree getEfferentTree() { if (efferentTree == null) { efferentTree = new DependTree(); efferentTree.addTreeSelectionListener(new TreeListener()); } return efferentTree; } private StatusPanel getStatusPanel() { if (statusPanel == null) { statusPanel = createStatusPanel(); } return statusPanel; } private JProgressBar getProgressBar() { if (progressBar == null) { progressBar = createProgressBar(); } return progressBar; } private JTextField getStatusField() { if (statusField == null) { statusField = createStatusField(); } return statusField; } private Action getActionForCommand(String command) { return (Action) actions.get(command); } /* * Parses the specified string into an array of strings on whitespace * boundaries. @param input String to tokenize. @return Strings. */ private String[] tokenize(String input) { Vector v = new Vector(); StringTokenizer t = new StringTokenizer(input); while (t.hasMoreTokens()) { v.addElement(t.nextToken()); } String cmd[] = new String[v.size()]; for (int i = 0; i < cmd.length; i++) { cmd[i] = (String) v.elementAt(i); } return cmd; } private void postStatusMessage(final String message) { SwingUtilities.invokeLater(new Runnable() { public void run() { showStatusMessage(message); } }); } private void postStatusError(final String message) { SwingUtilities.invokeLater(new Runnable() { public void run() { showStatusError(message); } }); } // // Tree selection handler. // private class TreeListener implements TreeSelectionListener { /** * Constructs a TreeListener instance. */ TreeListener() { } /** * Callback method triggered whenever the value of the tree selection * changes. * * @param te Event that characterizes the change. */ public void valueChanged(TreeSelectionEvent te) { TreePath path = te.getNewLeadSelectionPath(); if (path != null) { PackageNode node = (PackageNode) path.getLastPathComponent(); showStatusMessage(node.toMetricsString()); } } } // // About action handler. // private class AboutAction extends AbstractAction { /** * Constructs an AboutAction instance. */ AboutAction() { super("About"); } /** * Handles the action. */ public void actionPerformed(ActionEvent e) { AboutDialog d = new AboutDialog(frame); d.setModal(true); d.setLocation(300, 300); d.show(); } } // // Exit action handler. // private class ExitAction extends AbstractAction { /** * Constructs an ExitAction instance. */ ExitAction() { super("Exit"); } /** * Handles the action. */ public void actionPerformed(ActionEvent e) { frame.dispose(); System.exit(0); } } private void usage(String message) { if (message != null) { System.err.println("\n" + message); } String baseUsage = "\nJDepend "; System.err.println(""); System.err.println("usage: "); System.err.println(baseUsage + "-components " + " [directory2 [directory 3] ...]"); System.exit(1); } private void instanceMain(String[] args) { if (args.length < 1) { usage("Must specify at least one directory."); } int directoryCount = 0; for (int i = 0; i < args.length; i++) { if (args[i].startsWith("-")) { if (args[i].equalsIgnoreCase("-components")) { if (args.length <= i + 1) { usage("Components not specified."); } setComponents(args[++i]); } else { usage("Invalid argument: " + args[i]); } } else { try { addDirectory(args[i]); directoryCount++; } catch (IOException ioe) { usage("Directory does not exist: " + args[i]); } } } if (directoryCount == 0) { usage("Must specify at least one directory."); } analyze(); } public static void main(String[] args) { new JDepend().instanceMain(args); } } jdepend-2.9.1/src/jdepend/swingui/AboutDialog.java0000644000000000000000000000575710236624040020567 0ustar rootrootpackage jdepend.swingui; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * The AboutDialog displays the about information. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ class AboutDialog extends JDialog { /** * Constructs an AboutDialog with the specified parent frame. * * @param parent Parent frame. */ public AboutDialog(JFrame parent) { super(parent); setTitle("About"); setResizable(false); getContentPane().setLayout(new BorderLayout()); setSize(300, 200); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); } }); JPanel panel = new JPanel(); panel.setLayout(new GridBagLayout()); JLabel titleLabel = new JLabel("JDepend"); titleLabel.setFont(new Font("dialog", Font.BOLD, 18)); JLabel nameLabel = new JLabel("Mike Clark"); nameLabel.setFont(new Font("dialog", Font.PLAIN, 12)); JLabel companyLabel = new JLabel("Clarkware Consulting, Inc."); companyLabel.setFont(new Font("dialog", Font.PLAIN, 12)); JLabel httpLabel = new JLabel("www.clarkware.com"); httpLabel.setFont(new Font("dialog", Font.PLAIN, 12)); JLabel blankLabel = new JLabel(" "); JButton closeButton = createButton("Close"); panel.add(titleLabel, createConstraints(1, 1)); panel.add(new JLabel(" "), createConstraints(1, 2)); panel.add(nameLabel, createConstraints(1, 3)); panel.add(companyLabel, createConstraints(1, 4)); panel.add(httpLabel, createConstraints(1, 5)); panel.add(new JLabel(" "), createConstraints(1, 6)); panel.add(new JLabel(" "), createConstraints(1, 7)); panel.add(closeButton, createConstraints(1, 9)); getContentPane().add("Center", panel); } /** * Creates and returns a button with the specified label. * * @param label Button label. * @return Button. */ private JButton createButton(String label) { JButton button = new JButton(label); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }); return button; } /** * Creates and returns a grid bag constraint with the specified x and y * values. * * @param x X-coordinate. * @param y Y-coordinate. * @return GridBagConstraints */ private GridBagConstraints createConstraints(int x, int y) { GridBagConstraints constraints = new GridBagConstraints(); constraints.gridx = x; constraints.gridy = y; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.anchor = GridBagConstraints.CENTER; constraints.weightx = 0.0; constraints.weighty = 0.0; return constraints; } }jdepend-2.9.1/src/jdepend/swingui/AfferentNode.java0000644000000000000000000000326710236624040020727 0ustar rootrootpackage jdepend.swingui; import java.util.*; import jdepend.framework.*; /** * The AfferentNode class is a PackageNode for an * afferent Java package and its afferent packages. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class AfferentNode extends PackageNode { /** * Constructs an AfferentNode with the specified parent node * and afferent Java package. * * @param parent Parent package node. * @param jPackage Afferent Java package. */ public AfferentNode(PackageNode parent, JavaPackage jPackage) { super(parent, jPackage); } /** * Creates and returns a PackageNode with the specified * parent node and Java package. * * @param parent Parent package node. * @param jPackage Java package. * @return A non-null PackageNodeEfferentNode class is a PackageNode for an * efferent Java package and its efferent packages. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class EfferentNode extends PackageNode { /** * Constructs an EfferentNode with the specified parent node * and efferent Java package. * * @param parent Parent package node. * @param jPackage Efferent Java package. */ public EfferentNode(PackageNode parent, JavaPackage jPackage) { super(parent, jPackage); } /** * Creates and returns a PackageNode with the specified * parent node and Java package. * * @param parent Parent package node. * @param jPackage Java package. * @return A non-null PackageNode * Efferent packages without classes are never shown at the root level to * exclude non-analyzed packages. * * @param jPackage Package to test. * @return true to display the package; false * otherwise. */ public boolean isChild(JavaPackage jPackage) { if (getParent() != null) { return true; } else if (jPackage.getClassCount() > 0) { return true; } return false; } /** * Returns the string representation of this node in it's current tree * context. * * @return Node label. */ public String toString() { if (getParent() == null) { return "Depends Upon - Efferent Dependencies" + " (" + getChildren().size() + " Packages)"; } return super.toString(); } } jdepend-2.9.1/src/jdepend/swingui/StatusPanel.java0000644000000000000000000000155510236624040020630 0ustar rootrootpackage jdepend.swingui; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.BoxLayout; /** * The StatusPanel class defines the status-related UI * components. *

* This panel primarily contains either a text field or a progress bar. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class StatusPanel extends JPanel { /** * Constructs a StatusPanel. */ public StatusPanel() { super(); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); } /** * Sets the specified component as the current status component of this * panel. * * @param component Status component. */ public void setStatusComponent(JComponent component) { removeAll(); add(component); repaint(); validate(); } }jdepend-2.9.1/src/jdepend/swingui/DependTreeModel.java0000644000000000000000000001056710236624040021370 0ustar rootrootpackage jdepend.swingui; import java.util.*; import javax.swing.tree.*; import javax.swing.event.*; /** * The DependTreeModel class defines the data model being * observed by a DependTree instance. * * @author Mike Clark * @author Clarkware Consulting, Inc. */ public class DependTreeModel implements TreeModel { private PackageNode root; private Vector listeners; /** * Constructs a DependTreeModel with the specified root * package node. * * @param root Root package node. */ public DependTreeModel(PackageNode root) { this.root = root; listeners = new Vector(); } /** * Returns the root of the tree. * * @return The root of the tree, or null if the tree has no * nodes. */ public Object getRoot() { return root; } /** * Returns the child of the specified parent at the specified index in the * parent's child collection. *

* The specified parent must be a node previously obtained from this data * source. * * @param parent A node in the tree, obtained from this data source. * @param index Index of child in the parent's child collection. * @return Child. */ public Object getChild(Object parent, int index) { Object answer = null; ArrayList children; if (parent instanceof PackageNode) { children = ((PackageNode) parent).getChildren(); if (children != null) { if (index < children.size()) { answer = children.get(index); } } } return answer; } /** * Returns the number of children for the specified parent. *

* The specified parent must be a node previously obtained from this data * source. * * @param parent A node in the tree, obtained from this data source. * @return The number of children of the specified parent, or 0 if the * parent is a leaf node or if it has no children. */ public int getChildCount(Object parent) { int answer = 0; ArrayList children; if (parent instanceof PackageNode) { children = ((PackageNode) parent).getChildren(); if (children != null) { answer = children.size(); } } return answer; } /** * Determines whether the specified tree node is a leaf node. * * @param o A node in the tree, obtained from this data source. * @return true if the node is a leaf; false * otherwise. */ public boolean isLeaf(Object o) { boolean answer = true; if (o instanceof PackageNode) { PackageNode node = (PackageNode) o; return node.isLeaf(); } return answer; } /** * Callback method triggered when the value for the item specified by * path has changed to newValue . * * @param path Path to the node that has changed. * @param newValue The new value of the node. */ public void valueForPathChanged(TreePath path, Object newValue) { // do nothing } /** * Returns the index of the specified child within the specified parent. * * @param parent Parent node. * @param child Child node. * @return Index of child within parent. */ public int getIndexOfChild(Object parent, Object child) { int answer = -1; ArrayList children = null; if (parent instanceof PackageNode) { children = ((PackageNode) parent).getChildren(); if (children != null) { answer = children.indexOf(child); } } return answer; } /** * Adds a listener for the TreeModelEvent posted after the * tree changes. * * @param l The listener to add. */ public void addTreeModelListener(TreeModelListener l) { if ((l != null) && !listeners.contains(l)) { listeners.addElement(l); } } /** * Removes a listener for TreeModelEvents. * * @param l The listener to remove. */ public void removeTreeModelListener(TreeModelListener l) { listeners.removeElement(l); } } jdepend-2.9.1/docs/0000755000000000000000000000000010236624040012557 5ustar rootrootjdepend-2.9.1/docs/JDepend.html0000644000000000000000000013041710236624040014764 0ustar rootroot JDepend

JDepend

Summary

JDepend traverses Java class file directories and generates design quality metrics for each Java package. JDepend allows you to automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to manage package dependencies effectively.

If you like this kind of automation, you'll love my book, Pragmatic Project Automation.

Table of Contents
Overview

JDepend traverses Java class file directories and generates design quality metrics for each Java package, including:

  • Number of Classes and Interfaces

    The number of concrete and abstract classes (and interfaces) in the package is an indicator of the extensibility of the package.

  • Afferent Couplings (Ca)

    The number of other packages that depend upon classes within the package is an indicator of the package's responsibility.

  • Efferent Couplings (Ce)

    The number of other packages that the classes in the package depend upon is an indicator of the package's independence.

  • Abstractness (A)

    The ratio of the number of abstract classes (and interfaces) in the analyzed package to the total number of classes in the analyzed package.

    The range for this metric is 0 to 1, with A=0 indicating a completely concrete package and A=1 indicating a completely abstract package.

  • Instability (I)

    The ratio of efferent coupling (Ce) to total coupling (Ce + Ca) such that I = Ce / (Ce + Ca). This metric is an indicator of the package's resilience to change.

    The range for this metric is 0 to 1, with I=0 indicating a completely stable package and I=1 indicating a completely instable package.

  • Distance from the Main Sequence (D)

    The perpendicular distance of a package from the idealized line A + I = 1. This metric is an indicator of the package's balance between abstractness and stability.

    A package squarely on the main sequence is optimally balanced with respect to its abstractness and stability. Ideal packages are either completely abstract and stable (x=0, y=1) or completely concrete and instable (x=1, y=0).

    The range for this metric is 0 to 1, with D=0 indicating a package that is coincident with the main sequence and D=1 indicating a package that is as far from the main sequence as possible.

  • Package Dependency Cycles

    Package dependency cycles are reported along with the hierarchical paths of packages participating in package dependency cycles.

Why Use JDepend?

Before using JDepend, it is important to understand that "good" design quality metrics are not necessarily indicative of good designs. Likewise, "bad" design quality metrics are not necessarily indicative of bad designs. The design quality metrics produced by JDepend should not be used as yard sticks by which all designs are measured.

The design quality metrics produced by JDepend are intended to be used by designers to measure the designs they create, understand those designs, and automatically check that the designs exhibit expected qualities while undergoing continuous refactoring. Refactoring will undoubtedly lead to some adjustment of these metrics as the shape of the design changes.

Measure Design Quality

The quality of a design can be measured in part by quantifying its degrees of extensibility, reusability, and maintainability. These qualities are all influenced by the inter-package dependencies of the design. Designs are more extensible when they are independent of implementation details, allowing them to adapt to new implementations without internal modification or breaking their existing contracts. This same independence tends to increase the reuse potential of portions of the design. Independent portions of the design containing high-level abstractions can be extracted from portions containing implementation details.

The maintainability of a design is improved when changes can easily be made without propagating to other parts of the system. JDepend allows you to automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to effectively manage and control package dependencies.

Invert Dependencies

The goal of using JDepend is to ultimately invert package dependencies such that low-abstraction packages depend upon high-abstraction packages. This inversion of dependencies allows the high-abstraction packages to be reused independently while being extensible to an open set of implementations. In general, dependencies upon stable packages are desirable, while dependencies upon instable packages are undesirable. JDepend allows dependencies to be iteratively examined and refactored as an integral part of software design and development.

Foster Parallel, Extreme Programming

Packages that are stable should be the centerpieces of a loosely coupled application so the speed of the development team is not adversely affected by the propagation of software changes. Stable packages form design-by-contract facades to other subsystems, allowing teams to develop in parallel at an extreme pace. Moreover, by measuring the software design quality, the overall impact of proposed software changes can be accurately estimated. JDepend allows teams to identify and use desirable dependencies in the system and avoid those dependencies that cause changes to ripple throughout the system.

Isolate Third-Party Package Dependencies

Third-party package dependencies can be easily identified and isolated by examining the afferent couplings to those packages. Once the dependency on these third-party packages has been measured with JDepend, the dependency can be managed by effectively designing abstract and stable packages that encapsulate the third-party package implementation details.

Package Release Modules

Packages that are cohesive and independent can be released as autonomous modules with their own release schedules and version numbers. Single packages, or groups of related packages collaborating in a framework, that are candidates for independent release can be harvested by evaluating their design quality metrics using JDepend.

Identify Package Dependency Cycles

Packages participating in a package dependency cycle are in a deadly embrace with respect to reusability and their release cycle. Package dependency cycles can be easily identified by reviewing the textual reports of dependency cycles. Once these dependency cycles have been identified with JDepend, they can be broken by employing various object-oriented techniques.

Downloading JDepend

JDepend 2.9 is the latest major version release. It includes all the minor version changes.

The distribution contains a JAR file, source code, sample application, API documentation, and this document.

Installing JDepend

Windows

To install JDepend, follow these steps:

  1. Unzip the jdepend-<version>.zip distribution file to a directory referred to as %JDEPEND_HOME%.

  2. Add JDepend to the classpath:

    set CLASSPATH=%CLASSPATH%;%JDEPEND_HOME%\lib\jdepend-<version>.jar

Unix (bash)

To install JDepend, follow these steps:

  1. Unzip the jdepend-<version>.zip distribution file to a directory referred to as $JDEPEND_HOME.

  2. Change file permissions:

    chmod -R a+x $JDEPEND_HOME

  3. Add JDepend to the classpath:

    export CLASSPATH=$CLASSPATH:$JDEPEND_HOME/lib/jdepend-<version>.jar

Building and Testing JDepend

The JDepend distribution includes the pre-built classes in the $JDEPEND_HOME/lib/jdepend-<version>.jar file.

Building

An Ant build file is included in $JDEPEND_HOME/build.xml to build the $JDEPEND_HOME/dist/jdepend-<version>.jar file from the included source code.

To build JDepend, use:

cd $JDEPEND_HOME
ant jar

Testing

The JDepend distribution includes JUnit test cases to validate the integrity of JDepend.

To test JDepend, use:

cd $JDEPEND_HOME
ant test
Running JDepend

JDepend provides a graphical, textual, and XML user interface to visualize Java package metrics, dependencies, and cycles.

Graphical UI

The graphical user interface displays a hierarchical tree for both the afferent and efferent couplings of each analyzed Java package.

To run JDepend with the graphical user interface, use the following syntax:

java jdepend.swingui.JDepend [-components <components>] <directory> [directory2 [directory 3] ...]

For example, to analyze all the Java class files in the $JDEPEND_HOME/build directory, use:

java jdepend.swingui.JDepend $JDEPEND_HOME/build

Textual UI

The textual user interface displays detailed metrics, dependencies, and cycles for each analyzed Java package. For the convenience of importing these metrics into other applications, the summary section contains comma-separated metrics for each Java package. Alternatively, the XML user interface can be used for easier integration with other tools.

To run JDepend with the textual user interface, use the following syntax:

java jdepend.textui.JDepend [-components <components>] [-file <output file>] <directory> [directory2 [directory 3] ...]

For example, to analyze all the Java class files in the $JDEPEND_HOME/build directory, use:

java jdepend.textui.JDepend $JDEPEND_HOME/build

Alternatively, the text report can be written to file using:

java jdepend.textui.JDepend -file report.txt $JDEPEND_HOME/build

Example output from the textual UI shows the analysis of the sample application, an example electronic payment framework. The relevant source for the sample application is distributed in $JDEPEND_HOME/sample.

XML UI

The XML user interface displays detailed metrics, dependencies, and cycles for each analyzed Java package in an XML format for easier integration with other tools.

To run JDepend with the XML user interface, use the following syntax:

java jdepend.xmlui.JDepend [-components <components>] [-file <output file>] <directory> [directory2 [directory 3] ...]

For example, to analyze all the Java class files in the $JDEPEND_HOME/build directory, use:

java jdepend.xmlui.JDepend $JDEPEND_HOME/build

Alternatively, the XML report can be written to file using:

java jdepend.xmlui.JDepend -file report.xml $JDEPEND_HOME/build

Example output from the XML UI shows the analysis of the sample application, an example electronic payment framework. The relevant source for the sample application is distributed in $JDEPEND_HOME/sample.

You can then transform the XML format into a format of your liking. For example, David Bock contributed an XSL stylesheet that transforms the JDepend XML output into a Graphviz dot file format. David's stylesheet is distributed with JDepend in the contrib/jdepend2dot.xsl file.

To create a sample Graphviz file, use:

ant jdepend-to-graphviz

This will create a docs/jdepend-report.dot file. If you have Graphviz installed, you can then convert that .dot file into a .png file using:

dot -Tpng -o jdepend.png jdepend.dot
Graphical UI Navigation

The graphical user interface displays the afferent and efferent couplings of each analyzed Java package, presented in the familiar Java Swing tree structure.

Figure 1 shows the analysis of the sample application, an example electronic payment framework. The relevant source for the sample application is distributed in $JDEPEND_HOME/sample.

Figure 1
Figure 1 (Click to view full-scale)

The root of each tree displays a branch for each analyzed Java package, annotated with the following metrics:

  • CC - Concrete Class Count
  • AC - Abstract Class (and Interface) Count
  • Ca - Afferent Couplings (Ca)
  • Ce - Efferent Couplings (Ce)
  • A - Abstractness (0-1)
  • I - Instability (0-1)
  • D - Distance from the Main Sequence (0-1)
  • V - Volatility (0-1)
  • Cyclic - If the package contains a dependency cycle

For organizational purposes, package metrics are only displayed at the root of each tree. For convenience, selecting any node of the tree displays the currently selected package's metrics in the status bar.

Efferent Couplings

The top tree displays the efferent couplings of each analyzed Java package. Branches of the tree can be opened up to explore packages that the currently selected package depends upon (Figure 2).

Figure 2
Figure 2 (Click to view full-scale)

For the epayment.adapters package, we see that it depends upon 4 other packages: the com.abc.epayment, com.xyz.epayment, epayment.framework, and the epayment.response packages. Furthermore, it's completely concrete (A=0) and completely instable (I=1). This balance earns it a spot squarely on the main sequence (D=0). We can conclude from these metrics that dependencies on this package are undesirable because it's both dependent and irresponsible. It's sensitive to modifications made to any of it's efferent couplings and not accountable to any other package. Therefore, it's important that other packages in the system not become dependent on this package, as they'll in turn become fragile by any modifications made to the details of the epayment.adapters package and its dependencies. As a concrete package, it's not capable of being extended without being modified.

For the epayment.framework package, we see that it does not depend on any other packages in the application (Ce=0). However, it is responsible to every other package (Ca=5) while exhibiting a high degree of abstractness (A=0.83) and stability (I=0). While not completely balanced, this package is very near the main sequence (D=0.17). We can conclude from these metrics that dependencies on this package are desirable because it's both independent and responsible. It's abstractness also indicates that it's capable of being extended to accommodate new implementations without being modified.

Packages that were imported, but not analyzed, are not shown in the efferent dependency tree. Third-party software packages that weren't analyzed, for example, will not be shown in the efferent tree, as their efferent dependencies are not available.

Afferent Couplings

The bottom tree displays the afferent couplings of each analyzed Java package. Branches of the tree can be opened up to explore packages that use the currently selected package (Figure 3).

Figure 3
Figure 3 (Click to view full-scale)

For the epayment.adapters package, we see that it is not used by any other package in the application. This confirms our observations of the efferent dependency tree.

For the epayment.framework package, we see that it's used by all the other user-defined packages in the framework. However, it does not have any efferent couplings (Ce=0) and exhibits a high degree of abstractness (A=0.83) and stability (I=0). This is a requirement of a software framework - we want it to be heavily used, thereby making it very responsible to its clients, yet be highly abstract to allow extensibility without modification.

For the com.abc.epayment package, a third-party software package, we see that it's used by the epayment.adapters package. There are no metrics displayed for this package however, as it's a third-party package that was not analyzed by JDepend. It was imported by a user-defined package (epayment.adapters), so it is shown in the afferent dependency tree.

Using the afferent dependency tree, it's easy to identify which user-defined packages are dependent upon third-party software packages.

Interpreting Dependency Cycles

Package dependency cycles are best observed using the textual or XML user interface. In general, all packages dependencies that intersect a dependency cycle are reported. This includes packages directly participating in a cycle and packages that depend on packages directly participating in a cycle.

The intent is to identify sets of packages that must be reused and released together. To break reported cycles, focus on those packages directly participating in a cycle.

Here's an example of a two-package cycle, as reported by the textual UI:

    com.xyz.ejb
       |
       |   com.xyz.servlet
       |-> com.xyz.ejb

This indicates that the com.xyz.ejb package depends on the com.xyz.servlet package, which in turn depends on the com.xyz.ejb package. These two package must be released and reused together.

Here's an example of a package that depends on the two-package cycle described above, as reported by the textual UI:

    com.xyz.client
       |
       |-> com.xyz.ejb
       |   com.xyz.servlet
       |-> com.xyz.ejb

This indicates that the com.xyz.client package depends on the com.xyz.ejb package, which in turn forms a cyclic dependency with the com.xyz.servlet package. The com.xyz.client package itself isn't part of the cycle, but since it depends on a package in the cycle, it can't be reused/released without it.

Customizing JDepend

JDepend can be customized by using command-line options and/or by creating a jdepend.properties file in the user's home directory or any directory in the classpath.

Components

JDepend can calculate metrics and dependencies for components: packages that contain one or more sub-packages.

For example, given the following package hierarchy:

com.xyz.package_a.subpackage_a
com.xyz.package_a.subpackage_b
com.xyz.package_a.subpackage_c
com.xyz.package_b.subpackage_a
com.xyz.package_b.subpackage_b

Assume you want to collect metrics and dependencies for the com.xyz.package_a and com.xyz.package_b packages, but not for any of their contained packages. For example, if there is a dependency from com.xyz.package_a.subpackage_a to com.xyz.package_b.subpackage_b, then you want it to be reported as a dependency from com.xyz.package_a to com.xyz.package_b.subpackage_b.

To do that, use the -components command-line argument:

java jdepend.textui.JDepend -components com.xyx.package_a,com.xyz.package_b /path/to/classes

Note that if component packages are named using the -components option, then no other packages are reported.

Package Filters

JDepend will ignore all package names specified as values to the ignore property name prefix in the jdepend.properties file. By default, no packages are filtered.

The following example jdepend.properties file will ignore all package names prefixed by java, javax, sun, com.sun, and the package com.xyz.tests:

ignore.java=java.*,javax.*
ignore.sun=sun.*,com.sun.*
ignore.tests=com.xyz.tests

Packages can also be filtered programmatically by creating a PackageFilter instance defining the filters and then passing it to the JDepend constructor.

The following example will ignore all package names prefixed by java and javax, in addition to any package filters specified in an existing jdepend.properties file:

PackageFilter filter = new PackageFilter();
filter.addPackage("java.*");
filter.addPackage("javax.*");
JDepend jdepend = new JDepend(filter);

The following example will ignore only the package names prefixed by java and javax, regardless of any package filters specified in an existing jdepend.properties file:

Collection filters = new ArrayList();
filters.add("java.*");
filters.add("javax.*");
PackageFilter filter = new PackageFilter(filters);
JDepend jdepend = new JDepend(filter);

Volatility

Packages that are not expected to change can be specifically configured with a volatility (V) value in the jdepend.properties file. V can either be 0 or 1. If V=0, meaning the package is not at all subject to change, then the package will automatically fall directly on the main sequence (D=0). If V=1, meaning that the package is subject to change, then the distance from the main sequence is not affected. By default, all packages are configured with V=1.

For example, a package like java.lang is generally not volatile. That is, for all practical purposes this package is maximally stable. Creating dependencies on it is not cause for concern. Thus, if you include this package in analysis, it's best to set its V=0.

The following example jdepend.properties file will set the java.lang package's volatility to 0:

java.lang=0

Volatility can also be programmatically set on individual packages prior to analysis by creating a package instance, setting its volatility, then registering it with the JDepend instance before analysis.

The following example sets V=0 for the java.lang package:

JavaPackage javaLang = new JavaPackage("java.lang");
javaLang.setVolatility(0);
// or
JavaPackage javaLang = new JavaPackage("java.lang", 0);
        
JDepend jdepend = new JDepend();
jdepend.addDirectory("/path/to/classes");
jdepend.addPackage(javaLang);
jdepend.analyze();

Wildcards are not supported for configuring sets of packages with a volatility value.

Inner Classes

By default, inner classes are analyzed.

The following example jdepend.properties file will disable analyzing inner classes:

analyzeInnerClasses=false
Using JDepend With JUnit

In the spirit of automation, metrics can be automatically collected by JDepend so that they never go stale or require visual inspection. As the software evolves through refactorings, the design quality test cases can be run as a sanity check to ensure that the design has not formed too many undesirable dependencies.

Tolerances for any collected metrics (e.g., the distance from the main sequence (D)) can be codified in a JUnit test case that automatically checks the metrics for conformance to a desired result and provides immediate visual feedback. Tests can also be written to fail if any package dependency other than those declared in a dependency constraint are detected. The existence of package dependency cycles can also be automatically checked by a JUnit test.

Dependency Constraint Tests

The following example JUnit test case tests whether a package dependency constraint is met. This test fails if any package dependency other than those declared in the dependency constraint are detected:

JUnit Package Dependency Constraint Test
import java.io.*;
import java.util.*;
import junit.framework.*;

public class ConstraintTest extends TestCase {

    private JDepend jdepend;

    public ConstraintTest(String name) {
        super(name);
    }

    protected void setUp() throws IOException {
			
        jdepend = new JDepend();
		
        jdepend.addDirectory("/path/to/project/util/classes");
        jdepend.addDirectory("/path/to/project/ejb/classes");
        jdepend.addDirectory("/path/to/project/web/classes");
    }
	
    /**
     * Tests that the package dependency constraint
     * is met for the analyzed packages.
     */
    public void testMatch() {
        
        DependencyConstraint constraint = new DependencyConstraint();

        JavaPackage ejb = constraint.addPackage("com.xyz.ejb");
        JavaPackage web = constraint.addPackage("com.xyz.web");
        JavaPackage util = constraint.addPackage("com.xyz.util");
		
        ejb.dependsUpon(util);
        web.dependsUpon(util);
		
        jdepend.analyze();		

        assertEquals("Dependency mismatch",
          	     true, jdepend.dependencyMatch(constraint));
    }
    
    public static void main(String[] args) {
        junit.textui.TestRunner.run(ConstraintTest.class);
    }
}

Dependency Cycle Tests

The following example JUnit test case tests for the existence of package dependency cycles:

JUnit Package Dependency Cycle Test
import java.io.*;
import java.util.*;
import junit.framework.*;

public class CycleTest extends TestCase {

    private JDepend jdepend;

    public CycleTest(String name) {
        super(name);
    }

    protected void setUp() throws IOException {
			
        jdepend = new JDepend();
		
        jdepend.addDirectory("/path/to/project/ejb/classes");
        jdepend.addDirectory("/path/to/project/web/classes");
        jdepend.addDirectory("/path/to/project/thirdpartyjars");
    }
	
    /**
     * Tests that a single package does not contain
     * any package dependency cycles.
     */
    public void testOnePackage() {
    
        jdepend.analyze();
        
        JavaPackage p = jdepend.getPackage("com.xyz.ejb");
        
        assertEquals("Cycle exists: " + p.getName(), 
        	     false, p.containsCycle());
    }
    
    /**
     * Tests that a package dependency cycle does not 
     * exist for any of the analyzed packages.
     */
    public void testAllPackages() {
    
        Collection packages = jdepend.analyze();
        
        assertEquals("Cycles exist", 
                     false, jdepend.containsCycles());
    }
    
    public static void main(String[] args) {
        junit.textui.TestRunner.run(CycleTest.class);
    }
}

Main Sequence Distance Tests

The following example JUnit test case tests the conformance of packages to a distance from the main sequence (D) within project-defined tolerances:

JUnit Main Sequence Distance Test
import java.io.*;
import java.util.*;
import junit.framework.*;

public class DistanceTest extends TestCase {

    private JDepend jdepend;

    public DistanceTest(String name) {
        super(name);
    }

    protected void setUp() throws IOException {
			
        jdepend = new JDepend();
		
        jdepend.addDirectory("/path/to/project/ejb/classes");
        jdepend.addDirectory("/path/to/project/web/classes");
        jdepend.addDirectory("/path/to/project/thirdpartyjars");
    }
	
    /**
     * Tests the conformance of a single package to a 
     * distance from the main sequence (D) within a 
     * tolerance.
     */
    public void testOnePackage() {
    
        double ideal = 0.0;
        double tolerance = 0.125;  // project-dependent
        
        jdepend.analyze();
        
        JavaPackage p = jdepend.getPackage("com.xyz.ejb");

        assertEquals("Distance exceeded: " + p.getName(), 
        	     ideal, p.distance(), tolerance);
    }
    
    /**
     * Tests the conformance of all analyzed packages to a 
     * distance from the main sequence (D) within a tolerance.
     */
    public void testAllPackages() {
    
        double ideal = 0.0;
        double tolerance = 0.5;  // project-dependent
        
        Collection packages = jdepend.analyze();
        
        Iterator iter = packages.iterator();
        while (iter.hasNext()) {
            JavaPackage p = (JavaPackage)iter.next();
            assertEquals("Distance exceeded: " + p.getName(), 
            	         ideal, p.distance(), tolerance);
        }
    }
    
    public static void main(String[] args) {
        junit.textui.TestRunner.run(DistanceTest.class);
    }
}
Using JDepend With FitNesse

Writing JUnit tests to detect unwanted dependencies and package cycles can be awkward. Bob Martin contributed the Module Dependencies FitNesse fixture that allows you to represent your package dependencies as a table. The fixture uses the JDepend API to ensure that only the dependencies declared in the table actually exist in your software.

For example, the following table describes a system with three components: ejb, web, and util. The ejb and web components depend upon the util component.

Module Dependencies
  ejb web util
ejb     X
web     X
util      

When this table is executed as a FitNesse fixture, and if the ejb and web components actually did depend upon the util component, then the cells containing an X would be colored green. Any other unexpected component dependencies, such as the ejb component depending on the web component, would result in the corresponding cell turning red.

Cycles result in all corresponding cells within the cycle to turn red and be marked with the word 'cycle'. The fixture sports other handy features, as well. Refer to Bob's blog for detailed usage information.

The Module Dependencies fixture is distributed with JDepend in the contrib/fitnesse directory.

Using JDepend With Ant

Ant includes a task for automatically running JDepend.

Java class file directories to analyze are defined by the nested <classespath> element.

Text Reports

The following example Ant task runs JDepend on the build directory and writes the text report to the docs/jdepend-report.txt file:

JDepend Ant Task
<target name="jdepend">

  <jdepend outputfile="docs/jdepend-report.txt">
      <exclude name="java.*"/>
      <exclude name="javax.*"/>
      <classespath>
        <pathelement location="build" />
      </classespath>
      <classpath location="build" />
  </jdepend>

</target>

XML Reports

Ant 1.5 and above includes a format attribute for the JDepend Ant task and a default XSL stylesheet to transform a JDepend XML report into an HTML report.

The following example Ant task runs JDepend on the build directory, writes the XML report to the docs/jdepend-report.xml file, and generates the jdepend.html file using the jdepend.xsl stylesheet distributed with Ant 1.5 (and above) in the etc directory:

JDepend Ant Task
<target name="jdepend">

  <jdepend format="xml" outputfile="docs/jdepend-report.xml">
      <exclude name="java.*"/>
      <exclude name="javax.*"/>
      <classespath>
        <pathelement location="classes" />
      </classespath>
      <classpath location="classes" />
  </jdepend>

  <style basedir="docs" destdir="docs"
         includes="jdepend-report.xml" 
         style="${ant.home}/etc/jdepend.xsl" />

</target>
Limitations

JDepend has the following known limitations:

  • Cyclic dependency detection may not report all cycles reachable from a given package. The detection algorithm stops once any given cycle is detected. If the same cycle is reachable from another package, the cycle may be reported more than once. In general, you want to aggressively remove any cycles.

  • JDepend does not collect source code complexity metrics. If you are interested in collecting these types of metrics, the JavaNCSS tool referenced in the Resources section is recommended.

  • The design quality metrics generated by JDepend are imperfect. They are intended to be used to pragmatically and responsibly measure design quality in a relative sense, rather than as a yard stick for all designs.

  • Java interfaces are treated as equals with Java abstract classes. In other words, although there are practical design advantages to using interfaces in concert with abstract classes, JDepend treats them uniformly in the calculation of abstractness. Likewise, abstract classes that implement interfaces are counted as abstract classes, in addition to their interface, regardless of whether they are always referenced outside the package as their interface type.

  • JDepend does not currently support the calculation of Ca and Ce in terms of the number of classes inside a package that have afferent or efferent couplings to classes inside other packages. Rather, JDepend calculates Ca and Ce strictly in terms of the number of packages with which a package has afferent or efferent couplings, based on the collective analysis of all imported packages. This deviates slightly from the original Ca and Ce definitions proposed by Robert Martin.

Support

If you have any questions, comments, enhancement requests, success stories, or bug reports regarding JDepend, or if you want to be notified when new versions of JDepend are available, please email mike@clarkware.com. Your information will be kept private.

A mailing list is also available to discuss JDepend or to be notified when new versions of JDepend are available.

Donate

Please support the ongoing development of JDepend by purchasing a copy of the book Pragmatic Project Automation.

Thanks in advance!

Design Reviews

Move forward with confidence by getting a timely and valuable second opinion on your design and/or code. You get an in-depth evaluation that includes a presentation of the key recommendations and a full written report of observations and detailed recommendations.

Contact me for more details.

License

JDepend is licensed under the BSD License.

Acknowledgments

Many thanks to Robert Martin for originally describing these design quality metrics and writing the C++ dependency analyzer from which JDepend was adapted. I am especially grateful that he allowed me to stand on his shoulders in adapting his work for the Java community.

Resources
jdepend-2.9.1/docs/images/0000755000000000000000000000000010236624040014024 5ustar rootrootjdepend-2.9.1/docs/images/figure3b.jpg0000644000000000000000000007636410236624040016254 0ustar rootrootJFIF``LEAD Technologies Inc. V1.01 3!>,/%3JANLHAGFQ\ucQWoXFGfgoy}Obu~Wa 6.@7*Gc  `'z\2.p9#{ް%f1JH]yǧZ9tj#)H9=8Ka̍W_p$m)71F=ORc;xJj-iٿzg=3K6Ȍb6=J|E"ȇaI;@P@P@P@P@P@P@P@P@P@P@P@P@P@ >y4 @t&S6'o|Rj`AJoE 8%H$qUή!e#Hq ]ʼn::Ф d?OR@>kv{/n=סJVk7-9f6H<ҫn)%Hv\uC էVg"5BrzRYd'1q;zU9 ;CX:j9ї BȊ1I`!624 m8 ήH* ޒxkeid1r>Vh~3 TdsU*墨=3V6 UՕc_Η8$o^K~0X˶(˦OF ;qs$5ʥ~:zw`kid22.<0> IԳq ?>!R~Eݻhɦx_ʉ |=S5M6_Ӯis.k$߻%ˀđJJ],\1ePGt{ϳjRx֒$D##pInӓjI=[yR9"U,]c)<:.ԖX[6v|̖<~3S͠V[dT$dhm5`$Zƒ(,9;┝MG<kPG<ʏy@_ʀ*?濕T*<TyQ5kPG<ʏy@_ʀ*?濕T*<TyQ5kPG<ʏy@_ʀ*?濕T*<TyQ5kPG<ʏy@_ʀ*?濕T*<TyQ5kPG<ʏy@_ʀ*?濕T*<TyQ5kPG<ʏy@_ʀ*?濕T*<TyQ5kPG<E + h$k"ZU NAh._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlIs>IP}%eK}'@˟O* ?/U._?6\ϤTlI\"kIp'Yhfh l7t2x(1z7Bsq1wes~j? ?h g`c@%K A2+D $82+ ސ!}O#N3@ k:@ @4]5G,!q$#\="F1e<)9:x'[I"讏0>}:J+&o/Țy T w)M1la^9yq[9g IT e~4K $#E&8b @}<raZ'pI(9~瞽8J*/uco4i!I w,2@<Q@⾝"f@rv0: ou$ 8g1..!!'ic0 19zc.fӧH7pn@N^L w9=EX ( ( ( ( ( ( ( ( ( (#@s@ 7|CUmutR8m]0]Ye$3l>q>N>֟EW `Fw $)F_n=+!3%}5e,eHb ‚1ʌrxDt1 %کaC _Ҁ-}["F+f'p@GTB#8>Pۃ 3 g@aъڭѕխ`q| Х¨gI[EI N .֯ ^\*olx:My:| mT 0(vnKp$m#DR\;Su]yzl㳯EuǚYbӉez\'Kmy-Y9jF~vVm^I=@aDmc$px?-b]7FldpU N(KŤXU!:)ly)U8͜ Fo%|+`# cӂfF鷹m3򎞽99 {\&f7w9?3rsۏP J)a\j>E-@p2O9tp5H|,3 0?Rx1h`$!1QO,mocT݌g2{iL}zVPId`O~9qd` c21``cDUQӏN@c.2&6ݜpG`v@'[H8i#eȐ@?G  ǁH?'{/tyJL." n%Fr0~fZZndD0O^qKc00G+̉ g- ˎAGVeV 㶟yi{#e 8'I<9v3nFɻF3d<"2n%*;( ( ( ( ( ( ( ( ( (+:74NO4?[%B,P]NWҮ扶.q=-;nUJE}GZdM,ϾX!#GbF;gEH (#x +mA hJYR#mRʠEI@*[$ҶRq2hJ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (+:74NO4?[%B,P-g@w'h)lU0 u9q sL۹c4mfw\!Op|`#() t/;0\p-|@'VBܓy݌q,[Z%͵>lW3nS2=W<dVIc &[<$iw1 ld1@ ͞e!{`1 ,8[%k4?"G zgnΆK{Rys;)':o2A3Np4.0c,s㡠#kHXJݷkm)?0<oj'Ђi':k C!>dS618@ͳ8"hm #0*yr=t}w+8hL{ܙ/9w!Mi頭a.Üv TP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@^A?ɿ rܿ繠>?F.:/ˍJ_*i qU(:yh|3&eHisrT@3O^Y,cFI䜓#$aA@P@E#P 0( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (+:74NO4?~kmqE-ŬHKD`HidD@Pv9^5ER@vՃvw@[j9jdMyjN,R#;qsր*6t5Q±Ge+dbP;/sYkD{@cbo=qA@S:"1^Kr!IzTmys-G%ޘ'%I;8S@u)#.cK`y ,6'sק/sq8w0_=ӎ9u{Bav8ǔѹ\#'9At$G3`A1 Sp@_]c=Llsg qܛ+a$fI3#|A/ +LJ$M*J>8#Ƞ V Kp$XwmRsאr{c9<~uE6bh9P8osڼd}u *r~V| 6R!!g-' x'Pic0$Q&W!UGNyd` #uF,&H,6 tǥ 2!($ Ir~Fy,H#>WdS`y{[ٵ/0Y1׌w>r0 -eomSh`1-,Nw@TGF\'9nB~XA3uOaϠۄ3\vF28q=(`6X,fHlmU\:*x8QmntP;B #B4r0A"2IFee#(lIAi B[':r}h`i`&XYvc7{t9K[c8e7da+ҎF$xTQU\=vb+`?u͋H+ϱF[=%\\G#R"y9%31${}c+KAa8'h`6-nv8hݑz8{J9FQFUpr0*K36\sN¥s{cN`A*B$2^\RG=84r0'I #¢*(`H2"MnP@P@P@P@P@P@P@P@P@P@s\'}{Ih x a9zk`-u;[tX8Ii߁tl?.: =BT5CQ2-%*Qnq:c.s^f*Fu@(vPS#߮w/>5K7EdaڌK1c3t2I/ۙ2CnU,Hsҋ3Xm8R@#'F=O.mw69$Gu%\$g;çj- PʼlO⋈=JY)fc1@FNGl.1Ϩ[ 2QB1c9u.hԠL#II s\BbYB`6gq:.z*vHiHcx4!̶< :/V='C bY X~lz\b˳bI; Nq qKh vOOLD3 ި_͖ .:dwUZ"mqB,X)Q;i'ɣU.`B2dc-c@J3m<pjm}v̬3$LB7oDq&_ip9¸I{{w Q|\t>\D=$m4Z Pn<55}6m8 AqM+oY7V%8;v8gU{6yc88#nH7gDY˻,۳;rF8{QfmZ+0& uPUqÿ;5}s)-M=SM *&S Hv2A'ۜ/7C@%193`1d"w1*pGzYV=6ݙA)L& 9lnpxg'n9ٶ#0Ɠ0v;c`E ݤIYrŋ;RH=C"UՐA T#ދ42!U+9ǘe>rOON>fK ڑn$푈psœ$sEk[FΌ*`38}b# :ڄ+pC(vcAtfvcq+mܐr瓑NxĨ]Ӝӯ~ïZb+\-g+`H 6 akqB@0lbxl{87YJ)+dvFܘ#>+ bR\Obzj I 2C2o R>zvp:[3MhmSJS 3 >a8+V7PQ͐l˻&灎8`h˃w5B)YZM %ٶ bK01zsׯXdy Мo~؈'u\21f>Kt9EI7?Yq<N>XepPc2zP/俓vo"Zofsf2&+prc+[a.C / ±o3bc9@YciHb)҆zu_ xZYH) }62L 6֗ GLr,SpTc=}=Ĥa!k)rʌ6nOT"qF%kn6.|bH`3Rkk:'P@P@P@P@P@P@P@P@P@P@s\'}{Ih-.kkk-c)#tv@>ScHI+$ cExg&7ȋ<9SG;"h`D_Mȋyw4s"/vE<9SG;"h`D_Mȋyw4s"/vE<9SG;"h`D_Mȋyw4s"/vE<9SG;"h`D_Mȋyw4s"/vE<9SG;"h`D_Mȋyw4s"/vEz"Œ M@P@P@P@P@P@P@P@P@P@Wuroh/h&hz}iS\ eתA(@OO%< .6?3 :(o$3]1&@]\|ۺ %d@LdJ-&A*[-8kWv1CmO3M ܈FJ/AS] nEI#9wȅBWs'ל@6Ki_ʎB660Ptӡ1@ں+dɍy/W=(n2,bܿ%D(!@`QGydn ; I㯨 :Ӓ6rrA8Ӛ4X% s Ƅ;rIM$uq,*G"0b@l^{AKc$q$[ s'~n 'kXg"Bʄ$ׯ? zZ9's@եxiuezr[u}[In`*02`Pm]RwPobBd߼@4U#Gmk@ k^塉c|p=94, (di 2W@ Kxmd7A ?8"-2xFV7 ߐ(dt}vFQP@P@P@P@P@P@P@P@P@^A?ɿ rܿ繠>?FVQD^8^2s5+Ym忷*lZN"2HXdi]V(BŖ%PYH#0ƀ%62DDAJ !5-bIU|`*.Fp9zCl/ 85y;>GOtb;Q `F(#'/$?A@ ~h~< sӧ^h IdhZL(W~B@P!= av 88{P1>y^x>G^@Pr~hD1 .(rG2;;Xgyⶆ9_;PlBG Q^(Hh:G m5@q?*[3: ,=tERT,@qʀ< "X^QK*7@lrG?*dJ$F!Րcīh/`(q=8$PKmrӠ h%n`N ABz1AKs$~4L^G姕gmیcbEikQ@] K#Y0ך.-@0G2 `4P cp?SC lr@:PJ#2?:i#(ƆA1Q~gր[h'xh#9FtK@ Qcˍ mP>Q}O@˅9 g?6hb#񤱷Uu#+hc5@0r;@PPX>r1p39ԢTAa@`S$m<. @7!p xp'v;phO7.YUj'>lloJj3E2!i$/Q@$G ԿdFhFW;1qg0priR &c@fXCƲ˽ N$m99sp FȬĿΪq3898#4/>гYF39nfyS9W Qװ̋V.wqks ]YQFp 3=HBiRWh$C!4*I遐CxegMخv 6A#7|Ӧ@u4j٣GB!p#sހ%]ݞtjsdg _M@ %$e HCc{Kwr,; ^pyz:yd39C$l,T6U[8$c@,5h$vc\n1'O8tbYg$o+* <y!Ǩxcޭ `}Td_j/g#PY'`gRp#?wGZuqm@m*r=3㷽Wwt G>ǽYPG2F[3GTv&HS[89x׎@&+HV!L^F?3}G^ [Ԡ)`1K2E1ݻJ'GY@B9PGqX ( ( ( ( ( ( ( (+:74NO4?]6QN#՚vRC1nFWYi-U{O 0wPi-qrLA2:qY –la *ey'q %ĶD#mggDIv)s m3Ⱥr[ @`gMkao~w٭woހ*6%8imÜ.yL)[yzl㳯0қ 3p\vwG~q>[2;qw aTm#;yd(=Z0}E=@9y<l?{*I]7 z2@bh?#QtRC<35;1'^>tEխ[WUX?*^&V{ǻp>̔*z<ky *b@#PU\+Aۓz6 I#@9IF,@TOlqqLDfq=sI,ϽʮУ'({gʑJueF$s0 ޖ.b6xLJ=[ñH8 Vik :EF@={ͤw'2F^l'OqbrG!^A hYKqochTN 9>6O6bCQܮ|aLO9㎹Y'{yR9cVO V GZ2JD\hZ<dE^#F9'lPvnRgGLހmm,GY7B8ԞCkX79X!0@Q0ʧI ~U^=&9TYShQB$pI,{PgK ơ#,T:m@ݻN"h B˹s {fř1cdW\<q.*v??Zn xX#EDLq<˽UOdF3rț0ۛvr;q۞9KvI{m\;x珽(E/sER>$W?eN4.g˟U]qZ ( ( ( ( ( ( ( (+:74NO4?[%B,P]NWҮ扶.q=-;nUJE}GZdM,ϾX!#GbF;gEH (#x +mA hJYR#mRʠEI@*[$ҶRq2hJ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (+:74NO4?[%B,P-g@w'h)lU0 u9q sL۹c4mfw\!Op|`#() t/;0\p-|@'VBܓy݌q,[Z%͵>lW3nS2=W<dVIc &[<$iw1 ld1@ ͞e!{`1 ,8[%k4?"G zgnΆK{Rys;)':o2A3Np4.0c,s㡠#kHXJݷkm)?0<oj'Ђi':k C!>dS618@ͳ8"hm #0*yr=t}w+8hL{ܙ/9w!Mi頭a.Üv TP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@^A?ɿ rܿ繠>?F.:/b >?ڿo7=9@2#;$t^zuq{-);#Φ5cE 2N$΀E$P 24( (,hEUQP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@^A?ɿ rܿ繠>?F.:/b)k?y?@1Z]2:}=jop)iB[k\H7Hrr߀0 M~Y&`$,T#9r|:+l}%8L!s@mTx-c;F>s3)Ԧ{q#W* 30~r5`D-n1E99>@J F Ӊ} s׃<9%4atayˍo<{r1-Ӌ#n9q'=AJn]|On9}R-X{؃L0wq1琽IC4V[Tvg B6s:uw_ȢKn#$Y6F nNq1h!ys _!3zr*O b+y~+m8g^ ZE,o,G#% 1on1b ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( MS>=$m4vA WSҮwI$.3 on@ɹcd_]S`%}JkWW4P줒I4<Ȯ5 +N3=7ɓ̖Wb&UME,͂8v1u84&?2d- qJq<\@Z-%Mlcyb .A -ݭOB:{tefcsupE?F.:/b*rw4MHvS$PI5hoe}) %r;0q8*@@P@G$Ǝi[j u8'@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@^A?ɿ rܿ繠>?F.:/b)k?y?@TAMeUʨˎ(`Sfh[3@pa(<Ȟi GߒYKst4Y%Gѩ9ôhp@lg8#>Jg[Z7;K~B3 XKns P3ckap$mm8N>b=x>bXFFǙv#hkD\N['@Áps:02 :I$f0<%j zPNeA?yݽx@MKD iiy<cמ9sm5D҈tToQy&[ H >=ې P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P{\&F)roa oPWpĻUIRBjd1/.ٰ\>us5۫(vRIRxR`NlښedW`'q K+I*좖fg;[:gJ Ͳ8a8Ox -l[&1R}\hn n'! q=~2\1ޏʌm``:x8I"'vl#8w/ &1w7x湞fb;Jzs#-,M89Ca 908Ns y8ڀq`:St"= sׁ a\J91S) 3=P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@^A?ɿ rܿ繠>?FoVGrI#A+nҚWv+=~Aւ԰&6#q=noqBlFw[9=H ^j^Kyv0UU˽A!Vwy}AQ$z[U`[iXn#P0K_)'8րΩs 4lpJ8@nagm_zhW$F~%Gs,<# &xX6NFO'hM5z.Hڼ?fyHD̐8HצG4Tcq/bZ9` doJ50\$c$0 2V7)~ocyf_1ͻN P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@^A?ɿ rܿ繠>?F,JR9br1Oi9Χ;T_-@Pz9X :@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@^A?ɿ rܿ繠>?F@ׄOBMp2[)'^W > p}><,\ یxH k 2\rמN|}";~Pۺrpch0ui0c}-o'658u^J*sǚ=@[Y/7VsĠ6`/sӀ;E&}, ,*;b=.rzҀ,stW2 u P[q9=s#[Oʓ\!g nY#%cgIv9@{*7n3 p8g)(ب#8g9c"\_,w1H2>f nh6ZK1fXF&.'w=:9{[t=+<(ʻNA_9 rFFiW7;3g ~y<㎞ÞٿMOu ϏVC=s΂`?y ߕۅͻr!pbMS?6sx%_OԌ #۠ _gхx=Öl#'۱j2(]ZWN!fQ-W eGZυ<1-GB?2 8$݄8;q܊ѷX-ĨTq\02:Gy W:e-2 f$]F,f9$VC=s΂`?y ߕۅͻr~\〮F m9;aL:-󬯽a1O@ +mV x1?]ŤwEC:HJ8Yݠ=q)(4 X.SU qqޞMlN:BS6m9I7o`{yx',\}YdRU3G8ghhLs `Ui a\NX+V X2w3@i.hO#v 3vM3JSvm=[_]#Ƿ0H]ؽ€s^&"kh,2 V$ 1Ѷ85+$l,("q'#4L"31o}q(WX.llx@tP@P@P@P@P@P@P@P@P@P@s\'}{Ih-ukuEc/'?xz`:R[}Fũ~#$aAOhB,YbUU1 hSm$H`DԠЏLPR$%QˏʍFgz!s1&͑k0m^8 cYڷOJy#1`~B!O ~z"0q~B%[h0X#`r9kh#3Pn@ Ē,c{:dGgk Vtj+d`wf`=:u ,f 16@Up00;q@P€[3΀qbrG!^A hkhn0s-o4:PNC lr@:,,BZ@0Fd9@2+,9RGCd~t׆'߾4o1v>Tr3@G Jr4\[At.`d!d@^hZkh#3Pn@@m o( 9?^~Ea(8:eRBrV4 3,|%˻#oʀk.UKu*GVtdr=h{xI ]Xnlgi\qu`,p4Io"jSBGQuІN[yEE`W!Fr29#ݜ0-\NЙPՉ >E̫^ĐmRGu0Gg:f Sʐ L2p3~C@ I8(,$O$Z q߬a(͞'^Ch'T-+92=(iī,b9a}.v8aހy-C$mst޾ϲ drOq2@]Fq2[F<&%F*[nv3ӦO ׯjΏUY>ɕq fA pa3GZGY^6 2 Q@ ( ( ( ( ( ( ( ( ( (#@s@ 7|CVCuq! ۽/Ml_MF+wvdSJij6ɡSܮ>b1ӭH i曳+#~gnyr+_f5 "bp[nH0(sCw`$ڠPU@$sg;X?{!5O,vt@1cGm EAx;:,eqL^et];W#\GK{@d!H€[yK$ pLK4j@]۳1ހ$.\Bm⸒}?q jH{t ,$(ʌdc$PP7Op '{ 14{old݌#VAt̷icXg*=) 0[\+Cp$1)+ ``^IMUR`cy\g$Ԁ!g€$$6yNۻg@QGqC$?%%f>[/U x@a(A?$|= nlp(dnWrlg =ڀ (%,IU\*2@Aր43tV豺H 11wvsE g 6rB6r3@iKkcom CˆYX`kD>b2[Oc"@kL?,2?kZ.m!Q-P@uq`2y~t( (P <1΀os9}8+'y8uF> K@ GY^6 2 Q@:Ps8@ 4xy],}Q@Ks\5Z0pu?:" O F>PuA` drN\ n'qG{ʀ%2FA ΀uA` drN ngA0{΀2d I:" O F>P~k-LӚ|Eoy(׫;h-`B2Ѱ`MFYH^#FVSGa8 Nq78'{@P@P@P@P@P@P@P@P@P@s\'}{Ih x?ޓF5mOa2vZ!VIcBpL),9Q<ڹ+-̗-gybGFH '}F-};/MC>eh!g5Ge+}#jvp#o|RLjKwt7H,Fr9\n?wWX-DK(v2rB(>a/c+JWs1"o;XD zF4RGoI "d7D~Vny9T9@ ŽɅ.0D \ @.&9f.#Y]A8]z݆@YNZ03I1dbLazcpQj.dΕ⹑ϕzX0 3 tf {ԁ(/#f #y %fc?h#y{vݍWjim#iebn @->nyh4eK8TZps(sP{iwECc]9zs?F#Ŵ>~KKfXyIMq h\*G0I'wr6>LM?r@ ;˜ɷh&8q(l߇ >'}/O~(d_ܟ?Pȿ?r@ {xqΪY&COoRhl߇ >'}/O~(d_ܟ?P<?mHNFszd"€El߇ >'}/O~(d_ܟ?Pȿ?r@"€El߇ >'}/O~(d_ܟ?Pȿ?r@"€El߇ >'}/O~(d_ܟ?Pȿ?r@"€El߇ >''gɌc_/O~(d_ܟ?Pȿ?r@"€El߇ >'}/O~(d_ܟ?Pȿ?r@"€El߇ >'}/O~(d_ܟ?Pȿ?r@"€El߇ >'}/O~(d_ܟ?Pȿ?r@"€El߇ >'}/O~(d_ܟ?Pȿ?r@"€!I,#F> /hwJCoߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧP~@z7loߧPXx?jdepend-2.9.1/docs/images/figure1b.jpg0000644000000000000000000020447510236624040016246 0ustar rootrootJFIF``LEAD Technologies Inc. V1.01 3!>,/%3JANLHAGFQ\ucQWoXFGfgoy}Obu~zo&բrN'\#'"qp?G|G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø?0oO4}W9G|Ø oo#t<2è~_n@&*ϒ~Gi1nQHހ߀]n@&*| }auDʹbtn~q ;)~rT)7c&ԵKxit4R~.Jٍ4+;0cGIr4i\?/u:uo4:"K!88$5(A=W4F~_֝Re}ZKYK -I HQ(3I/JNZ++YK{*k\=R_Ise]i%eS~8 yzD~+j.'ir˄i5{w ^TIE{WR t#ZiEkah\MfT#"uMiP6iӴ+m `2`1nY7?e UCh=l  ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (5|3!?ݓ@jƿY%2庆7U¼O!;M@mm>Kf 0T_}ƏoOY#4{z}??_a>ޟpGOh?ϯ>G,S}=>f 0T_}ƏoOY#4{z}??_a>ޟpGOh?ϯ>G,S}=>f 0T_}ƏoOY#4{z}??_a>ޟpGOh?ϯ>G,S}=>f 0T_}ƏoOY#4{z}??_a>ޟpGOh?ϯ>G,S}=>f 0T_}ƏoOY#4{z}??_a>ޟpGOh?ϯ>G,S}=>f 0T_}ƏoOY#4{z}??_a>ޟpGOh?ϯ>G,S}=>f 0T_}ƏoOY#4{z}??_a>ޟpGOh?ϯ>G,S}=>f 0T_}ƏoOY#4{z}??_a>ޟpGOh?ϯ>G,S}=>f 0T_}ƏoOY#4{z}??_a>ޟp'ҵLHQR9ǖE-2Kٻѡ'rSoS Mih{_z9)7d-i;}*əI1$trSo.5x{(8r{T޴%.o?پ*߀]\/mKX:8+QO)r d#ddu=V@;6Uʿo[Z*,LBH`q JyN\Pܠ$rQI!F N[ s;Р/~|_7rwTa8%Ο-ַ?h c9 {T6Y8%*Tߟ"򳻽.P/E+ur7?/G Au(Z1 UVilv?.MiJ Jpdc94ѱ[]9\EP@P@P@P@P@P@P@P@P@P@P@PeRePO@Ҁ "hn`;-V{葘d!{ Wlbewa y?5~.o?Əg ߃?G |mO'h~apy?4{?0m=\6~.o?Əg ߃?G |mO'h~apy?4{?0m=\6~.o?Əg ߃?G |mO'h~apy?4{?0m=\6~.o?Əg ߃?G |mO'h~apy?4{?0m=\6~.o?Əg ߃?G |mO'h~apy?4{?0m=\6~.>cK FOLd_U_T}~b'7?Ua ~O@n?/>q?1ߓP*_T}~b'7?Ua ~O@n?/>q?1ߓP*_T}~b'7?Ua ~O@n?/>q?1ߓP*_T}~b'7?Ua ~O@n?/>q?1ߓP*_T}~b'7?Ua ~O@n?/>q?1ߓP* 9"$#P]Ҁ9ǔPE?o 6\ƸvKE2S$' Ÿh ֜ ET4uBexn}axq݁#^LJ cGFͻ I<O; ꒘ػReHĞ^X@!QR[dg6w ƒ #C8#ms׎p 5 J"H+Ttpwdv Fcu|%: bSᮠU泅,2썐|1Ӛ\?ιM$DQm 6Yvs"_H8 ǒYdicӾ:] *RAp^0c`3׌㞹 ІB;+[s# ǯK%k) *W&& )8)݁foY>TlsgވETO4";!vb$| gay V-,ZФUHלcdQUq G'=yޒ&8HU\$S𧎹Leb0\ wI0N  | HE˒ %r v<1V z%;I3'ːΠ=,rudP )y<քHi8G7(IbÒxOq$1Fpİ/䴌pqS<{sp,ZL6\e\'u$dߨMj".|yZ[b`\ڻuy?rW1"g70RG4؈e+C4+:M'$+I:t& ;DoD$vp:D_6-se'I㟛=IA p^ʒGTcc瑞Jzz%;I3'ːΠ9Ws2E(TňfG4@Xًf$i3g'G 1iCg=(m=Y$OF"`gSҎhd3̰J3~@LsDJ7,D?N>\xs^ o0,x$'G:<H=WGFG,0A*A>hN9gh cCd#8$ mQ1c+8 8sDKGP#9<<Ԟ{֟4@};,C8u]0?ߐ&ݙJAޟ4@ݣfbcm&h:壶pq2z('8=)sEwhr:9O <V8Y}9?j9IoFI6AN=.hi*"5ڃ w8 :G"U(t[gݒ@>POR8ϩ%x$td{rX=?GQl$o2M凡,O=.hE`b$dK4ۘ =r}MImh^)-ّԫ dDyShXXoټ]ÍR ֎y-`\C>iDG rK8bO''G4Ps+I8v BGR~sDIlY-؀#sDyShXZż|1+iluZW Trrҟ4BcRλyاLq\ <.5BqMha@P@P@P@P@P@P@P@P@P@Pm=s^2(?~@3@ -+GӮ4+F{8< \lבT݀F a--gN_}Jш*TH P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@}'@׌(P7pkj4."\玝=C5̶T#?ʆ08%]!6cmຉaHԥeh+6Ary=hQmFRLaOheDcƮUPq?L/N(C GvcC9a$J$F!ՐcHbM#Eba@ڼp=mnyjʀ-P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@?x<Ҁ:)?ZG[0NЭ$s'G^G_Sv]5i2GQ| k.pO^y98pV aG4i-E[zӅ$2qgs@ SR0ścm;A,cO5 [YDSK.I;oq@:,x{8oQ@ I_!#C!b(:r3z}b+6=1 3`0pqs@ }p'(һR5 odd(VIV*1sā x (Si"pBA g#s@ж<ύ6ymv3ݜsӧ=(Y,Q|*7QV1@hsB8'OBh_7>Z98 pA<= +ԻIaYv;hP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@}'@׌(P7͖O]3r~yǿ?Z2Xon#G#O#8< p3 w3gOI#P(H 3(Y,eqL^֙,,A&N%h< /+N '+gvgٸ.$I;y8`ҥ(6Wb(Ġ8;pO<Oic,7*\xi$WgPt:M6pd1'7ObF<iP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@?x<Ҁ:)?YuO/#Ei 37Mz[JYd#!Ǩm4H"2JT{d@rOH ["3]$ԕ}MT W[*B@0s'Uj (2d I: ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ;]q\gk_tO(ͯ-`dfR2nӳ^^̂O0v(g?9+ǜZ#$Vf4X߷SLI k3\%"J~LhyA 欆NFro=nXv"=׌2I]YmY)Nl||ڝSԁrhQH<.U#4-Jn&rs[Hq{(stt J24.GYp0H#|w ,~t\aegy 1#p02 .D#c|ed89GBA'$y%Fz`8ӧ0 ,@̀FKc0WMK篕?qǗgfs3@]OiN!)pF (Cr~R999K{^KX"brdm!`z%kDa4b%i1 C\n=9mv ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (6urO9ǔPE?o Zoy - |He~I|6Q,VH"PG-L_t 9 c?tQk^Q'b<2&:(fѤpĐD#v>sހ$ (&@. qʐGI@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@}'@׌(P7h:O=}@6GD!>-F6y#'>J-ڥӳ8Rcӯ#֓>&])xԎ BdA,&gx劺a`tu9n@5V8g6mH{1nyQL-Q }v ˜l_acY7Iq ǘ]}Ӄq6=Ar<^qFI'O$G=8biv[S\A=ap;lOJXJ$HmGlsu$s .A -ݭOB:{R\>P ( ( ( ( ( ( ( ( ( ( ( ( ( ( (3o\$yA]?tSJ.H))C;[0i6WgQ L2#/mЋL\%D[8+ێݪ +YaHܮq^GH햿eWa?6u^x ǰ ဧ8ojo-C2w"ad(8$(yna'g[##.`Iq# &l]rPb%$˰q}~`q@mo3FP0\xe#^(7^Ci Hހ$T扷G"Sd@ )p۝B2v6q(&JIaso2k)`px/(kiT<|t8|QEj.ك@#Qj"F2pOU猏.P@P@P@P@P@P@P@P@P@P@}'@׌(P xJ[6AEIӝky.|;sn(Js duV99id-G(,e&!ty.F*/T_Oz궐ؖi%Y2e ރ8 cӘ}u|Iӡ6=Y^DMJ="]~~1{\kuB fGp' >W1%Yc8uH2  |q@5mo!Qq@G$BG~$Nu[y!X,'SҮwI$.3 yח6[%?xKI9>x}r\Xp3^@94f9.#cb E!%H qYzg ( ( ( ( ( ( ( ( ( (3o\$yA]?tSJl7s°[[)yJߥ4u 6vqDu'-'hXLqEդ@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@}'@׌(Pvw_1i_lᾱ TS22:P^̾[C,Xp[fyސ%%xv4d(i6Bm?{@ k>g.HȉI': u+é]k#Hhpv2ɷqCqݜpx&v{\")=[OH5g >\;^A`Pd0KqyܘU$g;[ժIN8_is{?Jy nDq%wRD g`f ==rx>nH5KɂCcpy< ^Rnou2.d%t4o.#,Ыƻw*3Td>l`TBG|>]ǧ$olb VX [F q#LQ[˨eo>Y,h ( HIE*ː0YqcZܦO<*[U$9kCtbOQw~ю;z|f"y`sR=p8< r\CI9>ϨР +kN.ď{ps Çkgw/{.$?xH}FAtP;muGapc$`Vqh>o8n# o&i3"U$ (P\I=W-!<ȘNIg 0laip4Q"{|[H=04ɧ\&u{FN`w &HG3<@*iwW~Qۙw?ˏ, |?IYlaC$:0ʰ@x*>M2(H Fn2{pCsqC'CS/|+Xde|cP,U4! OơWqi8(Q-w2yd>Fo-bZ?i3ۼSs܌rNGp RPu5+$l,("q'#4iK} J(FA vnˏC6xi:f& h4ELMcg@9Zpn. VTǹ z{˸ q&T>`2C$ۙas=z1 uۯ0ŁǷɟcހ.@P@P@P@P@P@P@P@P@}'@׌(Pae!x\i`'6lu?]͕,mocT݌g jaH#\DAe`÷";_yl:Nֱbp6Up[G0 Cn#A8cr3@ h=7ד~ѼPw/<Q LfF%$@  ,p<0dtb@B1$M<ݘ`Xc0?!@-\,a7O^64X9'4m5@q?*T$ٲ4_-v& p?!@DXR5 0A@(<`xİr 9?O>Jɋ@z?*r@ pF'q G={ʀx`74Eb*Hq΀yZy[vy{Fݸ1!+xPFF?@XY8{H&p0H=9 )pF @8@ khn0s1lcvwg~\9Qc2?AP!a2ZW.8~@z@@P@P@P@P@P@P@P@P@}'@׌(P['nMpdSXB1 wa5ө{pΈ1MGh.i2dAs 9='%mR8'ʆl;mR6s^:teʏ .q9|u#BbE /<Ox-!E$mN~"PM,K2;[$8$#c$F![SX~ctӯ<K;..ob(Dcm>@ǭ@:GޠU{dq>MR8co>O6C-2p ;I:ݫ]!v~PݴA13(X EgGp1p@<@~^IIb 'w [N%wq8ހ:@O$S3Ϳ( 0V sz89춯(]03Ns$z&I6$Fx=$,k,dߍĀV'=\b)$`l6 ztW `a14Ŵ|H9'<)g n3QFYh: RSfOo0Tnb-R|)ehWfOpy9\( ,ɰ3`Vl:v 6Еbqހ"i- *ĪI s qt%y |0x\I`P8?>a}` isiaeڳZ-ˀ`A46wq( sHC FsʞgSőQf=7dQc@tyJL." n%Fr0~fj*Mmy-/_L3+XhcDЦ#VLq1\K0xlqꄜ8<c4GV񈥍%S*)*T`ש'ڀ%&S.E7ˀ#$z =z5ţ$d WwMC.}}#m9v_yi;2p8ui"8aleS ey#'9( %.f$9;^K[RI4$p3kZrt{U%:+Fʜ<4p] 5g7Uӯz"leYNA*B2DD_i0?Q}/#~7lp7v99CyE 4r$<@6!)%uEU<\HȠ ]/a{״R|q# &l]rPy5cmGlaO9rsu`,p4^$ w㜃ppzռ0#n~zP_^ajA;Te8 < @KF'qod\C ]8ۜ[]y2A*$NprǿjYnuC1\@ }{ NNQl '$(Rm@K; $q@}@c)qȏ6?)~ He(LY7q#r$^ <nE #"$ ( ( ( ( ( ( ( ( ( (3o\$yA]?tSJc7opw;)KwpF@#?\[7 /Zsmo%χnm˜)\nv bZcg<4,h`%|y=xӤ.%(eE|ʃI@V$:zyL1[gzsnO[:t>f<Ҁ#k+Ț)G@cC˹O0>zKmnHAԶU4zetY\cQ랫Ǿ3O<6"[y{6~ˌ=-FK]&>%K#19$OQhͽȞhYHUTǜ䃟K|s2шmp^x]ղ@EIJ2o bȬP#%[PMrEog"Fe&% 6~^FH2bfXfH.0L#%vNq'r ( ( ( ( ( ( ( ( ( ( ;]q\gk_tO(ls@18mP)"ba?` F)^-\\r8$u)=iP@PUՋ`J0p?:uP@PYJ` ('p?*dW0N$3#p C}:ku3: a=H~t-5\e0A.F@8..`@3 0QNhZ`[iXn#@Q\;Ȑê0%hZkƌ0TQf8zuE-ffQ} idAl'q5ɏqݽ~kQO  rTl3/$|>nP5­'w@X7%PNy8ݸd^PPMy-8yڋۜ{d m'py%<@%evgć0d;G1EnMɵp2Nz(ӽבs4Sytsq!WF=GtZo^~FJxAhX1-y=@ 6=7|I $keY/ܢ1aG@r5K3ywa'޼g$n@)jS\G:Əb kVe†Hd뺀7#پM|vv1ی{SH'#vO''T2ֶ#%*PmB9-%vĄnm)Cl@Eչ`' <Σԁ>{Y{l}ͻq`=K!o?+u>,}RGIJĿe*27v8> ׼  69NVmB0Hmw{pCg\Md6 -`g?t@O@a+xPFF?@$Eܡ9R@ (6T-v3>P@Pqđ9S?%P@H򤬿_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}ii>_?*}iip'!1̤nB}Es2(?E pzm_(Zhտ@}QbWh8n)Yz,Fvyh,$(\vZ%D$݀睸^w7y&y^c9稠 ?%4p6gA\6=H{΀$ζ?>cycy[wCmی9!!,4FK \[o% i.F}94'uƀ#k}=nݦ2GcPޒ?%4ch(]$dNpG_Zl֖6gz0&6"eeYgrg[zKh6mlN+mz?Im/KGB#"w<:.-Ts74 >:_@62FDyu5 nbwXn# ci3]QFYwSEowmܳc>j:_@ KKٲFo1w.^99g[zKhζ?m/:_@uƀoIޒ?%4g[zKhζ?m/:_@uƀoIޒ?%4g[zKhζ?m/:_@uƀoIޒ?%4g[zKhζ?m/:_@uƀoIޒ?%4g[zKhζ?m/:_@uƀoIޒ?%4g[zKhζ?[cHuw_tO(AJ֟Q3@3(b>b yooǁ5(IeyW5vę7=N-ėSDJ\Bb,r}NN@NS\ &vPF:(L{@ .-Ul&f+2D`m+#x4q,D,{9 ާ@4٫r)Tč 獝g s\>@i9nmA3?7 iwLmaxnsbp.) cրEk#0ZS/22!Fp22Ỗkx,V|)210#g8=OkbG ;4a!j^H#;XxULO%_0[pBYpQGS1N'hj<_3ӀJ 8r 5̓;ArP~n?.ޣi[{{տd{ɕ6G|۾Q 5ɹsy|u8 wSqkn⾞G?2)pu^}ǭ\ =[DIt|Rq~< 瞝BE 4HÐd 3ۍ &۲fe|$VeW77rGa@ 9dbsOlP];H*,Uy k l . v'Ӎ>KmKQIpLQ;$ޘۭ3LRfMc8݁n#<N\][yo#<H@w󵵔FbVxP~@lFV :bP_H;^[jH!7]ţ d? 4h{$J;G#yDĞuy's>R\][yo#<H@׼  69NVmB0Hmw{poʂcϛ(X:^fAƁ_~_2{PP@P@P@P@P@P@P@P@P@P@}'@׌(PeYGC>QX#HY 8i26; g&-poqlc#ie 86 i'zPLZGʠFO'#@4 ,F/t!=s؎hzkmRywL93|$ jNyfd/I rx c ,Y\q) 4R qN@X ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ;]q\gk_tO(֛c?hM{g[>pj" Uh~>ĖRƐ:$I`,Od&Y慙BI7'2:W0t׷K+eF]pC.xxzPMnK6#H w%86NXa~╦}!/NBm8QӥJ1'L/#69(!-e7hF009O y$n11bFA{2;O2ԀJN^^M&qPhW$FT8ʀ!K襞Ux3m IaOHheIhtr(e8A%P@P@P@P@P@P@P@P@P@P@}'@׌(P xJ[6AEIӝky.|;sn(Js dueI.ȣG9 c,O;sueym4Џ\?8&3$ ߚmqiǑd"!\>Y\dnz{.l].$J(a¦$ ܋mAn C$k8-,zbXnPvmd$r1JHC"BYO@]۶yѲnq R_<ێx|:Hֶ% oՈpz9 Zf_"] 2 ;NīI$ۜ>>u#z$g#l ]7wo9^4˨|7w9x@ Y^{ xH9R)bOH;4 aHˤpJ)$ MZh2(`Q?HhtO %]I&,tk{2J&:HE眎T VP[Xm9aHf oր# ann! #؀4dRP.*Gbހ.P@P@P@P@P@P@P@P@P@P@P@?x<Ҁ:)?6X-g< CҚWT{8I:ȓۓpTg,@A8h\;$`ToP+{"y{r >_~DQȀ< 9/AG"(@|ϗߠy{r >_~DQȀ< 9/AG"(@|ϗߠy{r >_~DQȀ< 9/AG"(@|ϗߠy{r >_~DQȀ< 9/AG"(@|ϗߠy{r >_~DQȀ< 9/AG"(@|ϗߠ5['P@P@P@P@P@P@P@P@P@P@}'@׌(Pvw_1i_lᾱ TS22:Pr z> ^Ys:G+p=O[n'@ G8@SNhZ1(seo׿3n"[XYrG?{g9yhղF7mtqt#)jPE0 5ˍ1.=1 42벢3U$)Æk7e#v(aXZ܅iA94cPlQHcFs`F#``(؇ےOB΢FD+F2 8=H~SAq;&}ɳqU#ёSsԕp-p\9X$d^(@'(w2x4T mN@I[(3U H!baO1d`/*AUDCg,^O6Nhɒ7ف3'̌bXpNr~ NIc嵉qmΗ4@sYߺm뵲9OO S(O0Kd09?97/#I*$gpŽZB ÅEZ\JG۶o0q 9 CczqO $zrEHmUdt8~TӬnUY?$%(@WR}-e?8[34f9YVS*?/ӎ(ͥp紆V+~4]ё 0ASv*Z0J8~Di\G4@_'W۷f1 Yc ƃŽhX =J9Y,̻|U0e fcǗ /tAG4@E ;N%as 9DER tIsE~\V"n TׁR{Wtdx+ pA9 bظڸG4@>|'_+nݘLcҎhEfaG +? 9eBd;G4@Vwh 9DEK'$6O^isD VԱX,rcsO BR4s"֔}}4x7n*&=@€ ( ( ( ( ( ( ( ( ( ( ?zePO@Ҁ+-w1“&˓1i CIQlm|)#=r29r0\Bt'qi^Y%1" !]ߧ-7sv͞[o݌f7gJjbA/~l)ʯcU:P?C2?#cx8(8 PPXMR6fフ#@ S4ApmqkzWq*:y@o=z@ȲSNNz<3٠h)Pd`۱qH sk<8>N8`9zPIXH\8mh[wK&kYCE,OF$up}(:kc/UpFN03<h/ay$(z±$aW %r9'Pqꤌ0r29G`qڀ!l$Ve1Fp~AmLr<@K%B@6('u r9 ʲchq !^uQހ)j_je"bq;1' g[[Y$H]+XEXp]Kz|sx a[ r)˩ g߁`[ĒK"QB,;zӭլ7TFy m̶F(8m@ x{nC9ߐ%A=l`9zY 9X>U98h2<$rƪrU9SҀspѺCbIY2I;dc}"gLB1W=;rs TJQKc0Qn?0VSdz}93@9ⷷ$EgܢRXv m[Xn#$Cu@  N#rqg@ gLB1W=;rs}{3@Gs:MWGJ\89Q=dK P,BdrFx#B%de}ʬT2@x9_ ( ( ( ( ( ( ( ( ( (6urO9ǔPE?o s팗3$)nvgZh if6QSKPeo nY*nqqRyl.#0.0@rK`d t<hf}Ȳ0IYA>lӚ$`F2:K#;qw,cz qʟf'噹?ucWJnwGDnr1s@}.AkumXu=0MYxo.f),);nKKFh X0ǩsqľZ3+yF0cu>:;Sdܳ7'{[ֆi<k՝4u`*rKXgH%9_cg'4=E :PN%+xȑFY?@GY^6 2 Q@uA!s?H^x@pZ6 g΃-aR:\;Ȑê0%hC08?3QFYh `%20 "#p7pBd,8,PMs-OV2qu*{˰Q2N9'~t #!d)ǯ42:0` $z0= ]VM:ar<%=0(*.EլH%])23޺mqp-$Uݤqgw4 bde1FIWN3:P;QqunX 徂D?3u mn}YV;rzQh[^ZZ c3ЪcC-կU?Օ<>> h ( ( ( ( ( ( ( ( ;]q\gk_tO(l 2eo,#%$ǹ?>@O@a+xPFF?@PEđ)Sv`].m|O3R<#.ZP@6I +*#723?.bo<I$hCovp1~Fހ*iQa}pjÌ|=9}ޣxGnN@pdlw88<@3M[/ #~8<$9cϨ;^Fӥqf.710mAO?L Z !]@3#n8SNGC6=Jij^Y _黮 Bz(oalf4ڤ!ps>fOH@ԝv_ǰX7VR#@h#{>?Z@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@}'@׌(P7sPCKZjn'h# !aЌ``s9l=@sr9HcrcŔMd&dveu7b ^#h4Mj-xSi2 r鎿Jm6)2fPdIYRF = ghzo',M$Yqlc8qhIHb8$kTEN8H4c싋H; +` c-W6wXj ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (6urO9ǔPE?o Zoy tP-Zޕ'e>ݑ3~uZ 'Ѯ9mg HY# p;8 i@P@*BmYTwbH ( (#T ۔3)8*H?4%P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@}'@׌(P7df77#> w h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (6urO9ǔPE?o Zoy tP='Olc=444Q/ZYՕ]呸<1)]4iERT,@qʀ@ DXR5 0A@ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ?zePO@Ҁ-i?f-@*,I25Vmi#Kf[]dyX售 g>;Rbh#`I>c8< Ԩms I\.019 VhZb;q  Xn\|29m_̒1gVTG߰ndg ]>Rye=HІߓ.cgU1KҢm96#{rFcd"dppx g uw4WP[ۉ^TwIWi^]l*۹KEg, Ccu灐,BTtHYOW,@#s@ &H!P`9p8qҀ~b6ȢiDl*C7@>WR >a #dgr2=@{SI+-wg+79= t맽DWvP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@}'@׌(P7sPCKZjn'h# !aЌ``s9l=@sr9HcrcŔ\XI5 I 0,@0@AߚzʒFO۔qw`g٨'DKd< ^-p<^sFAG 99lz|ip%HQ]H6rÌ󹺒9`{hx)Rp9 h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ?zePO@Ҁ-i?f-@1jzTCT͖ vD$tÁhFh嶺܁!d H<:T@P@G, ePq݈"$ (ĨgxC~3 t?PP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@fI5/JkM1]C4n 'lp8QH $L3 zʹ_6Ъfi-#bIv6>^A 6޵cqJW m7S``ɿ@Zeaǔ9X}Ҁ(gr4d>dIU-Y >lS# o#FM|&[{w,q#_$hݣ9y*@ 1^G@h*mg ]}@b-)-A9'## Fnnk$Q('WQ񁓒HKT kg`> ~#=eƟj&S" %Krp Pj+,Amd~|Jՠ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (6urO9ǔPE?o Zoy tPpѬ!h?PX6/T+TG~qP5jbs u8O@,hEUQP@PB(r@r-HO@ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ;]q\gk_tO(ǿsm{N}9 9&Y5–1,{J7.thQv2#pTޠdN6* dq[!%J>i*&S]<0F\b2XmxON+1.;a<7Ì'~=8@#QD&iyOX+LP22yO Hs:F 88w84-rLPs7~^zV-fKDY_=fc t R mgyB; &BO=N9kw ¢CxԒ2T>b&8Ԟ,ʑ;n>UlP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@?x<Ҁ:)?ZG[.ݹxe`Ɍuu*e?(vť칆i/.&11eWJ&{bʄm8rǣpÓ@DdkIp#8lBx>]-ȋŔ8RA8:O4[$QD(n{nn=m _/ .Fy<3nǛhTITz t$๕ 2 Uʟ.<`xxU'$sPQo UbP !GNҀ"J٠!6s+K`IbN8+H!h4FrI[>O4- DQ ‡`GEn~a׃en{!ߐo!I \z @P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@}'@׌(Pe;Rdrv3-4i1غj:m~mϗ$wǮFT<FK^n@ dn3R;A $$Bd+{w|nٳml㞝9@-LR%b͓9UuʰQgf_?blotrz{jI>vFprd`r8<hjvQFPH6a#rz3PoV%GSo BYH GB(2G>bH̥0@9|t<h[SP撬7nTbN@$Pk_fLgzg9@ P~p:R@ :r29.l7l6cvqNBt ]'1'z`3;Wzxswp HNb@]}kK1HZ+Vv:Sv33+aqq[$c,5C3EiJoCdnx#21YsO0c$[T6Y?uw,c8hTuúaºc,!1lcN%XQ}Kہ=x{%! 7v**ˌqX$ ;z[{PM7=91й`2:y@qZ/#&$mx$Pn~\c9 {a7bL iDRDGT1ͥ唉;;22c~d8[IkM<琏ܱzq[iHK{~,(I"O#gߝq4B(XLFf 1)ܫcYY » e@8zP`k{m]mf-=A,77/+<ʯ+€sM=C)vqŅX [;ϱZ]$ /` r| P5݅ų<۷8 k2Ƌ-kl&.~l$ g&5 ( ( ( ( ( ( ( ( ( (6urO9ǔPE?ow<+L甠_SJ8PowgI'Yrrv t'X Z@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@?x<Ҁ:)?Gk!uF N 8# '# p+ᕾ$<%g=R[{k2Wc@VK(kd!cn&yDdpy#^h:ֱ1o' c,wd1w8 Rkh0'<"#վLd #^IxL6Kz'aɍYYrFyN#5o2һp0 ݡ=|B+ydn+ s=08P;w9Pc'9F(sax+yY~tXH!y1(xu5̺MOq i,`FQ&27$0Jr ldq@֨)Cy*ʼi9Gr&a NZSm? ?ߴcNޟ-YX-ĨTq\02:GGeNO~:s4( S aoq#$,^P3)+^˴I";QAF-jeoe} zJe1[jP[Ɛ!*- '-, BQ6׍rAmM0c$J%0T` 4') #{r}N]\x$̊|=@;s@zLugXǴd~h hԄy98c9c=_u{wѭ͹s_+|~?Zף4;ϝ,.))gzd ¹jaȑ/9'92x@452βFW H=?2[-Hb\jw~BKkPYeG#Ҁ4tgP\9,ʂOr@ހ.P@P@P@P@P@P@P@P@P@P@P@?x<Ҁ:)?6IX.-̟:,"FeaGPw{= 8 0[#Z". 䁜t͒hH$]eEAҀ IopĻcBp ( ( ( ( ( ( ( ( ( ( ( ?zePO@Ҁ*߶kie*8RX€A+9 mE¿7>2$t {7wfZy!yNN}oVQ AIl;q[\]$7j2bpN9).plt8q-ͧ:H$BH\Sק^Ki}:VI*X=H Ň^{n'ldb5]J!p>sy؃ usqӮJ[V_/Ȇxd*w1}0lcx^xs:q %"B&eh?vONPPe[q=GN8 N~D3!Sg=:BvӮn#Q3nhebKpp Q {c7:R `mIr8ϯ,Xh.bYv֋l>A78cM J%C*Pa$ѕl& /(.N܌whZWFF$ B @XO%<-%  9qHKc00G+̉ g- 8–mMeQ0@9@d0!C(6E;)<[P4`B 6!F8ܟ2{O2'>L8 |h C\]yp*l'_8u8Ce,>\"cˍT襳@NI 09<~١hn̎>PWtwB[6BNXcqi"|2J.2Tg< qDA)u/1'9Aߌw i` Tf[r8^0{'He]ȥXg`0 C\]yp*l'_8u8 9714@ Rr'#9gݳ΍v3g=Sa4kp!e=8*sGFu-0PN <O'vxECۈ#?.01לP[3\ɻ>|*@ X~ҩ,1N=c,m" 9ǧ{=ð$&tٖܻqmg&g(U n ^s@mtm\#ymv~U8^{%Ť\I y0*A6zdkv:6M21PQNG%ѬqFNXGnݮ-O /=;[KwyQMFN>'lj\Om: mo%"@[4-P@P@P@P@P@P@P@P@P@}'@׌(>O@ DXɞZd?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@d?g@(udwe syA]?n]p +O*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~^*~Ƒ F}Ichj?~%dG_I|[(NP6:юYф7 d9<$u(ގn8VwM*.Au@}sD\v,h+ rs1ߥE~wL@H K si,ezg,Ac=(Wf#Sa$v:c(ϩ\鱵 !B pA,O=cMxguXٶ\ q9`tYx# ۜq[et%P90ʒٟ@,ŎdPkhn&eʉ"گ#l1L6q#/bCT'qnEg-#Yd1'{4SED7ц? 9#s@x<J.#V?נ ]]_u- `p_ xGٌm\cjE(cn[Jmycǽf<Ʃ4ހM-v!FzI4)vY :P-ki$^'w Hu#+>ހP#Օ60_O6; hic[dNy94\Gun:l|& r>hYYLmvF X[K2"<1 (Hd$>CZ[x&# q biFh v#+=)#nu a amm6g=3@̲ȶ"ckr0ho(X; hic[dNy94(`Y /#9P(Y@U >g%"*$@am,,l&6H#[}m遻:@(cF€bw&,H'>}/;n3@  FB@>[}m遻:@)1H€bw&,H'>-I#ȭs2ހ=ߴ-zoGb31=8am,,l&6H#,6ΤF-&I'J/(X<=b/(X<=b/(X<=b/(X<=b/(X<=b/(X<=b/(X<=b/(X<=b/(X<=b/(X<=b/(X<=b/9T<ΣN1ɼ|Pnj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(!nj ?5?ۚ?€O~@?osSPC(F03@jdepend-2.9.1/docs/images/figure1a.jpg0000644000000000000000000004254310236624040016241 0ustar rootrootJFIF``LEAD Technologies Inc. V1.01 3!>,/%3JANLHAGFQ\ucQWoXFGfgoy}Obu~Zs(Nz?uԚPrwSAO?Zq9J S;kR:ð]֥?t{v Կ_ΏcvZKa.kR:=;mj_/G`K%0a保?/ð]֥?t{v Կ_ΏcvZKa.kR:=;mj_/G`K%0a保?/ð]֥?t{v Կ_ΏcvZKa.kR:=;mj_/G`K%0a保?/ð]֥?t{v Կ_ΏcvZKa.kR:=;mj_/G`K%0a保?/ð]֥?t{v Կ_ΏcvXu hdd TN[H.ΑlJ{#Ȉf\>냟PY]W9\%y$Ћwn4I%ȌC)@:u9;IGbFI=Dդt0B$mȾtڠz(ShEIt;Qdy%iWbzcޮ5 iJ*0= I<_XY Λ?>0Ft}3vO,7t}fadݓ3 gMYY#:od?'GfAΛ?>0Ft}3vO,7t}fadݓ3 gMYY#:od?'GfAΛ?>0Ft}3vO,7t}fadݓ3 gMYY#:od?'GfAΛ?>0Ft}3vO,7t}fadݓ3 gMYY#:od?'GfAΛ?>0Ft}3vO,7t}fad*oOG r$M07,{V|H}ԫtz1 U, , k\@aq,glj3 tq ^39BB= +ZiV֒$o1(o_=#@7{F 4nph=#@7{F 4nph=#@7{F 4nph=#@7{F 4nph=#@7{F 4nph=#@u !@<ϹTSZ@Lzt^""L+(nis׀?|v0y$Zw@:8Usi6|;GNN1M! {R#sSB\m;sqh&#TNzҋ]FqqNU֎3?JW@5`X c8;4Wy>G<<]ŷĪ=ϚwW)ęL7sJnQ*Qڝpc p Qx,) Ss?j] PPPPPPPPPPPPPPPPPPPPPP0!Ix?B:YA#wE4ItO8"g 0W"wt,AH35V`nnĸ;7=nD_J-+ H*̹fHN0qE`¥C:˰.%qÓ޼w˰+DVV"e{wSܔ`s9d˰ph]mne`A$ǧx*$fb:g1 ۙ`ŽU6I"BGqE 䘫8˰ 12)sd:ϵ]rXƪI~H e (pAhiT%_,g(]z2m79Ͽ[\nG\Ĭx9 W` 7IEdu?0iX _C}d?@!H4}d?@!H4}d?@!H4}d?@!H4}d?@!H4 *<4k?B:kƒh೶L2F7"qE;3gXʞ0E=>\E*_h|1lthc%n vDzTX|99n"vK{vq_qӮHz )$ȣ9xOڎv؀b'{ʎvaD18hQ`e˕ cQ_F{G; ,99X %6vcx(aa~4s-K98Z9XAc 򣝀ǜQ}/~ҎvŴ/8se9g𣝅)Fs9XX cM.f ( ( ( ( ( G&8gBP]k!1@jܬ{Uw`_6 T6 8 ҿx 14X QdGi vYXpAtBIN rztፃF m1(j( ( ( ( ( ( ( ( }}Oh+?uֿ?7@vAmnK s#c(7>x}8#1!UIA^X[<3#I<E`t;h]1{=Ԏ0pGtW8Zrc'4b[9$0I'<P@P@P@P@P@P@P@P@ZHV  o(B2ax -.A GXS&#ndZMNǧ@6v#c %[KP\P; pwpݻr=;&u/1UĎy'?ҀP'U\pqہ@eOK4=P@P@P@P@P@P@P@P@ԏMqZg? q)CJ"rz(m.}"[JClc q# v4>]o )v[HE5I~}c~^YAϱmI>fwq9~zt hɴjNYF7yt@P@P@P@P@P@P@P@P@ԏMqZg?Bb/a@P M5&L.6@ u94a$2 v?_J@5tbBG`Ӛ?Xyq΀or0:7P# hRG ՘I==(Q0B98 z5i$lXLg@F9 P@P@P@P@P@P@P@Pk#@V!Y(I*YHcsEoķM –8SVo[xn㧯Rm,KpxyDr<%U6 3_qHbBX`Ҁ -[~,W!NAx3@MV 8#yDʧ;h6#+ qs=(Khƀ.0  y8׭8M):_qc?΀Aʋ+>dJY6(Aʀ#IVY1n[ߙ' HA @P@P@P@Pk#@V!Y(*rDk8u?Ҁ,1ao(;w$cLN}`&v{^yg27iڸ@SM`5.?iNXT`gSMfi`sr9^zO?{v*ʻ:wʑ*B$s@An$c.ǦyJDoKo@rN3z@rn">݃ 9;P%g2TI):PF6e %xKL$ 1eCOUC Ek䙷!zgdd1_$ 0Q?7 (p66 EU|@pt0:1@]yP?'GY:9|$}@XX$ Čp Oa*9zo|uP05*$nݱ"OGE^}oT9m}W?qP\ @㟗i_2\F8K@iqۑ}L`_n~yWDdOvaקA2X1'߯;PPs(]cߧjc_3|7Î=xo΀!;A"RN-yzw@4&2A;l#. b'qSxߞ;Ewo0:x\A#o[ix_j'_dT8q~t\7Kyc1oV g  pz_( ( ( ( (+_Sⵟ !@$xDÞ}@d[ג5ban% r?TmJ73q6:w!$'گA4rHn琿L@ i Hw$:>PdW,Bv=ڀiϜɌq =@7ǵJ@c{ `0 >)Pr96I.&U)1Uޜݎhi @,mqz1y%ϴ zSQxfqOG8^9o@t~d~|Ȣ-"1C`{'aUϰ 3m Õ1 ( ( ( ( ( G&8gBPI,E4D*[4uY9qU$(Ԝݏ3=uzȨ3I-qOC˒Cd;3PX䫐aŽH9(Qu86;<>x=ǵ8_pEFH8nGs@8 HzuCpPE [cGրm3ʙm ;*kO8#;qor6N3ONhVFP7x'?1Z?,ae\=s@Ȅ TN 1]+I1Ө #" 1VP>'L^^"n?#bc;Tm=A<ƀ=,Avbww$ywE EH}(VCm3e>< u@"e0KcǂzcJ\RP@P@P@P@P@ԏMqZg?Bb4(03s@ZZ(02:P@ 3ր ( ( (F4P@P@P@P@P@ԏMqZg?Bb4( ( ( ( ( ( ( ( ( ( ( G&8gBP]k!1@P@P@P@P@P@P@P@P@P@P@Pk#@V!Y(q ( ( ( ( ( ( ( ( ( ( (? +Ye@( 9 z(Eq!u s(EdIhi8F}8 <€qp:€>z/p9P}n?z9ӟҀ\/ϸ(? >q=?POy}_@q=?POy}_@q=?POy}_@q=?POy}_@q=?POy}_@q=?POy}_@q=?POגi?LzP+V O1g`Gs)` `1W0 RBK9#щD[.HvT7p -|ɼ?Z%BP8ǠM(TNF3lz[bD~4>fǰ |6lzOG0n<1{c֎o mX֗0cd sja1Ӿs9`msӯNii!, cc=:_- ~z}Ɨ0GI9c{f6{f 4mhGh=3@6{f 4mhGh=3@6{f 4mhGh=3@˅$/V 觑cMKcߎһΆȑ.fTIf]R8 rTgNzSdPuJ[i_,Ikd͎>-PlQwx7#ei1<3qi@3UX!'r0⾙;|nm,m*ۜr~9Lp),f,|G>b;`NpI 6h<`8c?=-r>m`3LsրcQ\ˏSӥ, Mc_,_QaT8lNpb6 ub&C$8ڜO\@ ^KxbX+9@RaosxMD1ۄ @4$ +1u\s߹^Z~x#j БB(ǑOPC<y$ED??@OPC<y$ED??@OPC<y$ED??@OPC<y$ED??@OPC<y$ED??@""c@ry ?h+?uֿ?7@Krk<"T8 lf Vup:pIRV߰3HlnQ@2$g1wi[>X<}ۀ7+l`y z'9&`y# #H  ( ( LP@P@P@P@P@VR>A4k?B:A}Ŕ9=ZXKtИ^<)mӌg5`mhB0o\Rp%o ۷d`}*`3:G_J amSx8?!P`\5f ~4:j#0y?ZVZ(7gcP팠|f1܂qfh|`p$1SNNq1*ǻaʀDϷoRFzPѪbI@J ;'_JOC;ڀq7/@C@ gJd`}{C98ֹcLY>$3A@36| Jrt *  ( ( ( ( }}Oh+?tfiΞ^2I`szi1wɴp=UܴCpNOSsʟbAxBfZ&226ӍoaGaqɇ*O@x?SG X{0G(ySD#!Nr{04ݕPs{6B̮-O.(F ~qnم>I*:0q:9dWqzu.=$HT{6y[#q4{0-DPA\u?*=\sy!H^2A=8~haqH1ݹ\dsΏf HC1?!Q(ԺyX۴#ffD˂c4r-fprA=8,P@P@P@P@Pk#@V!Y(fn>\7$)h7$b1VRsGBzs+\ cKg6gv1V] L$f>:.eLI̬F>ך.gdUI aYLN}x m* @T&==41ppn?Ep,%($ эŰ \*㑅r_N=e3[*ߌ̀K .[s@~ )t`u#*F=h@cF}b+N{gގeh}Hhe>q@+A 7رon]D;FA9㯿_A"\&0H-г)&0wv7-x:5ǰ&ߙw<2?O? p&m#pw{ր%Wss"0R=@cD %w);G]€''E6KIxRpO:Iu)hTR$I]nUS:$#mN=9,S%,[i@{[?'78]A2۴'8R ɠAo79R>\s׾~Ms2Z"leH'i8M4l RGH ld3/ď@P@P@P@P@Pk#@V!Y(q ΂K[YO29C*OB1<~4۫l1Oi[ۖ'~O#vꡉaH?:p1FU@[9$c;[,C}> ]`H$hdIN (P@P@P@P ( ( ( (+_Sⵟ !@uhPM?)aA.)/1?.? /Os@ip2 G< xplp1-h?26ttٰ@3x]2%U䥕$Xެh[k4#cquP( ( ( ( ( ( ( (+_Sⵟ !@uhPdxk{$eCdo@3L6b67_o9HL4)}i?w9ycҀء. O]7@k{l}{q򞢀o|f3arG$q~-!YTh.xg'Jwwg]fn9GF:s@`GH#Is=Os@P@P@P@P@P@P@P@P@ZHV  o(B2H` Q\ ϾyKۄ[W*~n|{g۔ ۦbK/>QO S@,P= #ha*N{@--jX)Sv(m&L[8U1ێWHJ6n03@P@P@P@P@P@P@P@P@Pk#@V!Y(Gh%AՈ=(ڄK$H:q׵6 )hPJŴ{ոYH9~V۝FO8k1Ԅߧ+ϸHU` _2GQKE0j*`K|g(@RAێ::(?G10A9phP@P@P@P@P@P@P@P@VR>A4k?B:#rZ= 7 ]G Q[*`.qw@ UӃ|r':}(iY,Hq9 )68?jQ1򟧧(5>TBo^~ |7L B_zQ5@|##q@ # ͸*7c@ $~s9Ӣ(/F#T^'΀I9Ϝ`zP Fw?:CqM67t?\,.X@I%& ۺn' @T=P@P@P@P@P@ԏMqZg?O03Ϙ#4bnfljchmJxӭGݻB8Ɛ"6G90?@4PIrFv.({yq1QpKO? 찉7!ncן?F"j |ǀG=E 6ЁGv8d~Tfo +`g{΀ĎJ @@ UIf!9;zP-rp~9pi^F޸>F:ArOVc <xh% %C*2y9ӷOjQK3L8|`;~B}sc2<ʌ#JImb;v1?z( ( ( ( (+_Sⵟ !@AW{#]0éd yE ܻ#n:`Ft6݉8#aH=5_2vmW}C~t19b6}nz?>M<[P.FtB?@ Ϙ1sI>ҀhLmq)^>,On4eYW`NR8\A|cx^hU-ĒeA?@bh"mmIq|^hclMr(Pp z}@ ՜˶EQ' ,9@Op8&\NA }}~@tfY?vFI?Z'C3o#|#P}s@[$d.۲{5Y KUHSנg `w/^{Wr gac @ d_/܋Vpw?G29bP3 ,w_rXd߭Xtv&V`ឣMЃ;Ǘt70.f[N@&ibhaI͎j8C/af@ i|, +r{sg3|A}n}?נ͹@s^6mϣz<۟Gy>}n}?נ͹@s^6mϣzC% 2sZ+NPOs)a7m{΀)b]}ޯ:?N(Ee!HnBq-}{rBv@xnՁ:L4zvQc_ؓ)Fqg^@(H4VKVH`(g? SN=>[o+ `;:8hcͳBv۹A9sɚHYl\9A>^5@'/` u@ u͹ br@ 8I,dۦ_7˷K}6HLCo 7dCgOJCn2$z kO$ | ^(ϙ(#<9kӵF4ݖ"9cPyx1€!G/d-ЃСJknñ ,bqg.ؠaOP(}Sl>}6Tb ?@ؠaOP(}Sl>}6Tb ?@ؠaOP(}Sl>}6TrZ nP@ @P@P@P@P@P@P@P@P@P@P@Vo?jdepend-2.9.1/docs/images/figure2b.jpg0000644000000000000000000006206210236624040016241 0ustar rootrootJFIF``LEAD Technologies Inc. V1.01 3!>,/%3JANLHAGFQ\ucQWoXFGfgoy}Obu~Gp\i(ТF.0v:5jJ8`J$dqҗ+J,Wgu9X |Di0q| P$qO҅ u_mcnj_BXU`H$zuxHm .AMG[mcn!Iد/Ƈ l~SK (-Pq.#=;CVws`m F:ϵSB%dBMN NZV&+jҤL(e8 cMG[(Rʧ0}p}=rjv%NQ4_Q\8Z|}2Q];G@}TXp^Tm"Vdl:@l:<tyEc=͏z/@_΀6?违l:<tyEc=͏z/@_΀6?违l:<tyEc=͏z/@_΀6?违l:<tyEc=͏z/@_΀6?违l:<tyEc=͏z/@_΀6?违l:<tyEc=͏z/@8#(BLP6 pjְ_0*d F8>Z|6+G.F*s sC`,!@덬}Op=uxG9 vdbұ!RA@GG0Gl%[=;gғK71(.*F9暒, Éd!A1ǚ|zfZO1̊ istX`򄠱>cfIĶb9nM;;A$<pjcBil!dK|ѕGz|*Zl'ܿ!c@bag.p_( }3O@G 9G/b-{RRdY2AQR2[76mϚv ]:j@).ʜ~]sesx6UsYˆ\LQ͠ [# Ãu洑 8۴(t~s$` 9p˂@[J9cr&2Fz.*NZX̒aIeЏjjV I$f c8 ZGoιӔCK;sO,9${cN6 01߭; :Fp6>shȬ] dz} >di!@ ˸ |X[/0 h #Via# މ  ( ( ( ( ( ( ( ( ( ( ( ?'GɌF8(ٯ?4I%0Y6CQlCss<\3s<ٰfyEGap&fᛟ?Mͅ7?/= n_4{6 (hl.Q\3s<ٰfyEGap&fᛟ?Mͅ7?/= n_4{6 (hl.Q\3s<ٰfyEGap&fᛟ?Mͅ7?/= n_4{6 (hl.Q\3s<ٰfyEGap&fᛟ?Mͅ7?/= n_4{6 (hl.Q\3s<ٰfyEGap&fᛟ?Mͅ7?/= n_4{6 (hl.Q\!u #&; _^8?i}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4}yO@ٯ?4UWBLZ?'#y?iY.IbITT`'#TԴ㰻n.,nԮ9ilsLA䤿,^at݌*A;8Ӹy1? ϷO8\]V8Y2 \r>a}}99RWp I dw{p){w-E`)]`Ԝ Ӝf SJE$_(m1L{uދ%K%QE އU}VN,V[uff9_^Gs-"qQp"T|c8qE&C`j`rqLpe|n݆ d NIy+GlH[wI{ D1yny8N#rj1ٞq(`hl{r;YC!ǘ({g%̞ibU;%S躌3N Uwx7d"7<U`X7T`ON1J.D`v3p1luSB#i^xhCFY'*)=2K)w4:dZF7mdtXHk98cO%SOIO4eBbE@Mg`ZJ]Ŵ=Y"ٳ1dt*y kFM6fYg_*7f~rT瑂8..r=| L)fdEP*rq׎M-kmVyO78,nFF:gc1 ;.4P\`3m81iFw([Q! G=qZww K$Gy>F ##dRX>kh˖;$vQugRU7N23֋-լ4jD8t$g$gg46c۝D/c<ɧp-<dqӞ J#* q; Xθme\cW][S1r~S94ҕp+'V#=:`OS.Od:H,2 :dr?*.$VL)q(U<ҝ>ۙDLr613p9;YΠȲ^e = t4i * `ۊw@2 'Fif gsMwgi#~99}p)w3f%PeY۱NF::`ӸGm$aF[w;9`sӦp!Kk|}@ dR@{Sǡ& {Fi#v2<{utZXd@@t88~T$VL)q(U<ҝ ѠO3nbYzv]@sZIʾF@1 " Sqm,D(HP`G Y'y/@i]wZ4)΀a;>^~:님-P=„4gӚcѷo 1b~SIEbyw{qIn`I7z={PMFycX#h9l,sڀɒmB#u,81I:k;u(Df&>O,+@N'8red%d~IDX X"_M4c@ERLt80ɴg(==N-YʲUTg˔ǥk@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@??P4T=O@P]JH#vDEL[Cn%:@3:K;T xX6O~ͤ6>18lu ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (|\BJ@Ǽv <xj[nhcw#u>ߵ (s1;H q8[KHDP19<HM}ymDӡ1Ie>8ב|H'* 'n7gM}y5qF#>pڅ662yag,(W2 $4)8/r4b[]'DIخf`:Kc=c4FI. "Iax/_pCc2H^Db!yKlb^@8s@9K9h\y/GRI?@ i}ܥ?eGks~lqV5"x!96q/)}/ q^P/sq8w0_=ӎMk772_ϔ1>z ٠ P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P+?M?'#y?SS0IvldMh@Aq Fh!dzu@54dB]ŞFvʜ$yN֐7Y"ܞYvP=\W较60g6a1/CyJ,L't Vb0IrO^A@K[Ȑ';#ۘ9T##9F=%m>H,g1P?0's4Ed v>LH;FrO_zi>O|?*:?*閅"O(aC ?0ShV̧V˷_ʀv@XIzsPP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P+?M?'#y?CY,4 KTȠ9kp+ mno )'F;q z]辱YNJJ`=@<@N05[e 7G^',!9 HFǨ@ u 26Qqo-UCqĐ*>s$R"Da(LMm8`h UI2džGPUk!I UlWsOLpy4an`kY3FnԎ@ }0PtLsMרDvD;Ö4ƼFE{Ub YI`3Tؤ5Pł%8?: ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( Wr (OEGu' ( ]ѫMn1?`RyԈ=kcr8e|۱ 2O.hRTdQ!9YH;'່] "yc2 -o~i2%hYO$徙%IRhK>WyŲyh#f!Ac@ M翞PEA!F\c=`Sle(uGP?^q@{Pы78<6}0[^V݊o)A @l]?Nh?ۢѕ|ǹ=h/P8Xm"D y`H7U@tu43 rTx7@6q FgEۙA7'<= .4dq6I5..L7.="9rӜ TP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@RI@R(;=l4Vg"z~&fxH@޽ۑ~Dm' >LV}8ݿ!M+*{7el-ar3NQB ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y1'В)tPw_'rzwᔤ79>D '߰6T]LK-y=f}1D[p~/w4Y0B# V`8+'8OAkyy-^yb;b<.63> u o<"d`lGy?xg(9ImJ'rx9ZPNӘ5Lc!$8G90g" !Aq<&exYElpH Ze"r :y<M%]\'7qBl!`2F1\\h4#Ƙ63|^wqҀ"/.Hx<N1b ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ()^$ i?{\6.`[Y$$Qq@ kk d)nwV0]ڽp1:a䒽:qLƍ.ʃyOhxb}FcAܼ}G'4AFA$dU@fvc}-{ϭ<,ѡY9@ ~h~< sӧ^h~d(DTJb% 7xQ(}GA@ ahw0vG,1[h0'aP< "X^% ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( Wr (OEGu' ( ϱUmCS*𶙪EwĂ9?~-ѹʟyFڈ܁H T0v$((XN qdjQ$ pM-JҪg'$NO# U]$% BI#<m}hW7ﷸ_-|>~s@IF#7cj;c y;#r9Tuݕ>Nzvx?mEiRp[Hy$Md3‡u$62p˜@Q$t :.7: RO5b WH$`*9q"iw|PIr}@j=GbW≮fzac9 ]X}qoc}HF/iP ǠGbza|'wڀ*ir\#,Vc f/#Fˉ#܍<רڀ ,Y6˹aYT svc~TѤ)IHՊ dz}~i;Y)$Uj*$'tŶd\RARrV hNR\\#Jq]0IyϧrMU,(}9+)Bz}9@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@RI@R(;=]]Pȋ$V7F28h`z;03<q~h$89ǿzFڈ*P@Ppʓ6Pq2(J( (1*߼E $T%FҢJ3|gjS:s=EGo{or"rN7 PIadr=E {nBߒ!I@l`9@/aMaLdn?>d<dL'@ hf8‚qz"+U(K!Rv0 =EX .R'$p=TFG#P;d)<Y9=Rx6T`PGb@^8I\X bpy8C@(!?7f?Q@ 4FI[jlI"+U(K!Rv0 =EI4oJcK1pɠ ((n!2d9ـPnnT3jz('4{PDpC)VSAv<mVD6pNG>ր 3H7z8 ( ( ( ( ( ( ( ( ( y1'В)tPw_'rzRM2Y`ePA 2:jj6/ݢ^۳4.$>VOZI- Ys*&U+WX cIl 'E9(!8I2^q@ `΅ZvkCwV+W: )ț9SCȷ<ϗp74Om3knaѴN- r ʞy< ܖus8S@x͵[ȅ4f&\99{dnMFT&, (8Uv!b,|$9ր'$A 6n㽲9݀ nMD6 w6#>^/u4Ԏa"ycq+[vݭt@ 8 d+{ӠKHdy4yV26'B[y1B6d3\W' !vZDID09Sw= =ʼnH t,ϯqѨ.!_, c/=21j, |8g)7 "ȥQB'9p2Ny<!s}Sg7ߖlcgzfk5@bXٕ r~y!Gk, fxRdF|3A1dska ;;A`NX x$ggΒ}漆d! R>pNx@Zuͼd&E-#\Y2< v:1˷ky<[v+$N7|'} şb u9<@ #%ޥw,0H2;pG#+'$G!`~E\NW#ԭ&yDI7ll lM;qs`g=~\~r`.=#Qp?Y0 pG;@KNti )I*99%O\f+Β}漆d! R>pNxsVFGHԳTd({7ɱ6{lv |>Lʱq倸DH8€7-$dr[ˍ'kX@ŕF@N:FFb2cJ‚@؞ae$6n=T&}~א z( ( ( ( ( ( ( ( ( (|\BJ@ǼD\ V73X+4{1=`Sia&.ߛHrx d~PUKP 2?*uP@P@P@ dV*YA(r P@P@P@P@P@P@PUKP 2?*uP@P@P@P@P@P@P@P@P@J>cO%SOIOzBw_PIr q"s2g8=pii6y?w{RwӽQq<+3K leP29 #@"dK" c srVxR#3ۉҪ?ju@JD/\(m&]ebA tqg1rF%RfiH#0$c5H8W;aLD($d8 ?Nu{%mfBBrElю[GS%UH|w8=0q Ap12qʭ:IHm<. 1Xľ[0=8!2_.c. aQHm빆y\\\A˓ifh9 +}x[hF`'Rqހd$6[˒m ݖ ϧnF.6nqq!R1)P3x :t5[t61-q4j ( ( ( ( ( ( ( ( y1'В)tPw_'rzr[m$s&e#?u`&ϟ''xten{!ߐo!I \z U|&<Uͻ'o΀m@Rlڭ#0=5Cl!w`ĒH`r:t kc.p3>};P6ʑ# d=~@ ]>`2쐼˂1qo 2rFpGOD+,YglI8th>fJNNw> {u sn 8꧱A1\lk@\dW*#=OZssFF2p8`EبUT@N@ 1_"SO?*%&@. qʐG$9܂:P"S;JNGS2hܠIAb84ĐD#v>sހ#p'Nq0r9>w1ov@a$g`P'99$;P6V^$ h˖=PDcrz{yjlݠJ1Ŝ'Nr00sqIc|Ĝ=%ࡠ8pCF'4$$I 9 I T +G.-@*YO#qhi" $'}M1tefn9br0y<G4-vR y9%1${}3+KC8'h\\ᣑz=JjaUF*jdMg)i;zӯ4iT)b NI=ǧN^=>ZR)A(cbE*= ~THLa$,ݴHϠqҀ h!BHAՏr}IKZ$svnkXw>wހ%{t'a* c #Pk;$ )ڌ~eTqpN9( }&BsE"; w2zҀ;DdyJ,+#݌ی@cu"^۽ǐw;RGP$`x>,T~SF>`Ohж<ύ6ymv3ݜsӧ=(mBbI7;HٛT Gjl.U>Rb@!G^NҀ]IlX~^>zpOqK J䕰q>çԨ9ao.aoIqȬKb## s4[ 1p ׯj t\[G7 BG^}@%5.,8$Alֱo?64#8qOH˨ɻa\3r1ߏN^Pkg$!!4ľ'n;s~)C{,\6ˑXq?RFF@y ~J$uFh o( (FG$gJ-.q*X_cm˝xaws($}QUI s s25Qď*̌b&g~y4rr h/NkK4h—ut#z^팷m)xa?ZM-Ry9%II36 1叕9'C@%T6Y?uw,c8h^E[Z̈́ۨd%VE#?L Gq/nąQp3O V3J_ NbRON\24`B#X39,9\3M Jl(֗*n%'_P:|@`dҦs; E#'PntTG)[y7e€AGNv{bPb?/nUK( 36P?Y(v km ugm/F;鹋L(:p?䁗Q.O(iE7؀vldĊT²$QGuY » e@8zPhmeYbaI.da?쌁PP@P@P@P@P@P@P@P@P@P+?M?'#y? Ecq$l#pyS>\͐Y:'C?/{ma@P@G <nE #"$ (9%H4vJPc?sƌ0TQf8z&m1w(s~>Ac4 lc:('}ǭJ"leYNAn!ByC&A?8 hIę9= Q\ ʼl38}( yIRx4ʓ$z;xjJn8B0@Wr9'Pqꤌ0r29$T#$GIw$ܡxRЃy-E%1M 2HIvK@Eq "E fH#  yIRx4ʓ$z;xj#$y-mq"($)I1"5? hktPD~e Xxu`,p4^=BL|·p\I!`0 cO%SOIO `e5 ʠduՄ7Rl_KDfh\%RI}鶬[CFUhLWkc(9oӃڰƒ%OrPBpt+d㌁y ,l33X#2W-u dg5;R;7rn%x1.=d~oӞhfh[3@p`h)t`Hϓ*&\Y%BӒ@4]ovvcef sB2A Qg>dbϱK :XtR@`f#@ f #?" +\gPMmo4Xg FW<` obmm9ۍ>@zZH)Yeޅ@ r2?1@/ѷZΪYmTeDZOZwc<2c3D8bSr v Ο+LZ-KɃI%G I> ^CR<`ɌL@fɂIv;RPed[Yغ5q2\,01r#'#&A ڎVK9;$3}XQנå.gz, #0eib?5h?FAц u9# v Q~v1-4 %t!̅WaRy qzd =ᤎUU۷,s뎧|(7cO%SOIOIj 2 \ +ƣ>bPsޭA⹧P1rx d~PUKP 2?*uP@5Xeʒ:c#'P@E#P 0( ( ( ( ( ( k"R C$t8GO@ ( ( ( ( ( ( ( ( ( ( Wr (OEGu' ta[E+Y6SioNݜsއ`4Y-HZiv+n6qޱR;*أ_U݌{ZtȯG;j`q}EK{{{^DUi݃]Aqc=pS_[}3w٭}o/?<.`ݻ8w4C=ۼe b8׌v4g +-ụǯyVLG flLwqO J\=^]H-a]XĀ*;xH ;)^kye^:ϭcik{fFާnO ڏmcM`zضwE'e v_.4Q#p2 MķI0I?1 7 鎃=M*?(ԙ8zu9Р gw/{.$?xH}FAtP;mK[o԰BcwQZi:\^1@o׼ : yky ?tF #N$ր/_ޛ_EI@ Ԯ̰ q -1(HEU4$ےOh.aI7Gʖd{:zZ!y%Uu'c@B+ko[Ʊ0XڮKQdk</!U4# 庆] ^ <1+Đ$:uV30E-DLk `9_3PP@P@P@P@P@P@P@P@P@RI@R(;=]]Q~ЪԠ:N}ё+ n ꋰ. Sb46ꮠ@C.k+GBqEAM(Y*0G>7gǘfPmq}}11>y^x>F᠌΃ !A@z?(!1H9?GgkQ@p'hm\-ABp:k1;4= ~T;(,T0EB(G^(b/*hcp} 8~T-$I`B ! ?!@ h mxcdW=@-bpHܷTm' t V"z*(~0<[COѪߊdFI20+ = :#b14F4;h\|F᠌΃ !A@z?=QTU:c'Em#q.Ȁ>ש,"FeaG% `X@Jˆvn܏ÏEb*Hq΀@- p bwi zװ[h0'aP4TB*PjaUFERT,@qʀ1Ba#^8UpGy],}OS@dV*YA(r L^G姕gmیc4#$N4Em#q.Ȁ>ש ss 9 "@[A+ pF)ʢ s>qm9}yxb}FcAܼ}G'4@.1@KG gط}b ( ( ( ( ( ( ( ( ()^$ i?(u۶2z&7I"{x(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW??}_"?\+P>s|@~.(CEhW?? /w`F =1F#@x;EHv ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (hjdepend-2.9.1/docs/jdepend-text.out0000644000000000000000000000725410236624040015713 0ustar rootroot -------------------------------------------------- - Package: epayment.adapters -------------------------------------------------- Stats: Total Classes: 2 Concrete Classes: 2 Abstract Classes: 0 Ca: 0 Ce: 4 A: 0 I: 1 D: 0 Abstract Classes: Concrete Classes: ABCGatewayAdapter XYZGatewayAdapter Depends Upon: com.abc.epayment com.xyz.epayment epayment.framework epayment.response Used By: Not used by any analyzed packages. -------------------------------------------------- - Package: epayment.commands -------------------------------------------------- Stats: Total Classes: 5 Concrete Classes: 5 Abstract Classes: 0 Ca: 0 Ce: 1 A: 0 I: 1 D: 0 Abstract Classes: Concrete Classes: AuthorizeCommand CaptureCommand CreditCommand SaleCommand VoidSaleCommand Depends Upon: epayment.framework Used By: Not used by any analyzed packages. -------------------------------------------------- - Package: epayment.framework -------------------------------------------------- Stats: Total Classes: 6 Concrete Classes: 1 Abstract Classes: 5 Ca: 5 Ce: 0 A: 0.83 I: 0 D: 0.17 Abstract Classes: AbstractPaymentCommand IGatewayAdapter IPaymentCommand IPaymentRequest IPaymentResponse Concrete Classes: PaymentException Depends Upon: Not dependent on any packages. Used By: epayment.adapters epayment.commands epayment.processor epayment.request epayment.response -------------------------------------------------- - Package: epayment.processor -------------------------------------------------- Stats: Total Classes: 2 Concrete Classes: 2 Abstract Classes: 0 Ca: 0 Ce: 1 A: 0 I: 1 D: 0 Abstract Classes: Concrete Classes: PaymentProcessor PaymentProcessorConfigurator Depends Upon: epayment.framework Used By: Not used by any analyzed packages. -------------------------------------------------- - Package: epayment.request -------------------------------------------------- Stats: Total Classes: 1 Concrete Classes: 1 Abstract Classes: 0 Ca: 0 Ce: 1 A: 0 I: 1 D: 0 Abstract Classes: Concrete Classes: PaymentRequest Depends Upon: epayment.framework Used By: Not used by any analyzed packages. -------------------------------------------------- - Package: epayment.response -------------------------------------------------- Stats: Total Classes: 1 Concrete Classes: 1 Abstract Classes: 0 Ca: 1 Ce: 1 A: 0 I: 0.5 D: 0.5 Abstract Classes: Concrete Classes: PaymentResponse Depends Upon: epayment.framework Used By: epayment.adapters -------------------------------------------------- - Package: com.abc.epayment -------------------------------------------------- No stats available: package referenced, but not analyzed. -------------------------------------------------- - Package: com.xyz.epayment -------------------------------------------------- No stats available: package referenced, but not analyzed. -------------------------------------------------- - Package Dependency Cycles: -------------------------------------------------- -------------------------------------------------- - Summary: -------------------------------------------------- Name, Class Count, Abstract Class Count, Ca, Ce, A, I, D: com.abc.epayment,0,0,1,0,0,0,1 com.xyz.epayment,0,0,1,0,0,0,1 epayment.adapters,2,0,0,4,0,1,0 epayment.commands,5,0,0,1,0,1,0 epayment.framework,6,5,5,0,0.83,0,0.17 epayment.processor,2,0,0,1,0,1,0 epayment.request,1,0,0,1,0,1,0 epayment.response,1,0,1,1,0,0.5,0.5 jdepend-2.9.1/docs/jdepend-report.xml0000644000000000000000000003417410236624040016234 0ustar rootroot No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. 35 31 4 3 13 0.11 0.81 0.07 1 jdepend.framework.AbstractParser jdepend.framework.MockAbstractClass jdepend.framework.MockInterface jdepend.framework.ParserListener jdepend.framework.AllTests jdepend.framework.ClassFileParser jdepend.framework.ClassFileParser$AttributeInfo jdepend.framework.ClassFileParser$Constant jdepend.framework.ClassFileParser$FieldOrMethodInfo jdepend.framework.ClassFileParserTest jdepend.framework.CollectAllCyclesTest jdepend.framework.ComponentTest jdepend.framework.ConstraintTest jdepend.framework.CycleTest jdepend.framework.DependencyConstraint jdepend.framework.ExampleTest jdepend.framework.FileManager jdepend.framework.FileManagerTest jdepend.framework.FilterTest jdepend.framework.JDepend jdepend.framework.JDependTestCase jdepend.framework.JarFileParserTest jdepend.framework.JavaClass jdepend.framework.JavaClass$ClassComparator jdepend.framework.JavaClassBuilder jdepend.framework.JavaClassBuilder$1 jdepend.framework.JavaPackage jdepend.framework.MetricTest jdepend.framework.MockConcreteClass jdepend.framework.MockConcreteClass$MockInnerClass jdepend.framework.MockPackageClass jdepend.framework.PackageComparator jdepend.framework.PackageFilter jdepend.framework.PropertyConfigurator jdepend.framework.PropertyConfiguratorTest java.io java.lang java.lang.reflect java.math java.net java.rmi java.sql java.text java.util java.util.jar java.util.zip junit.framework junit.textui jdepend.swingui jdepend.textui jdepend.xmlui 19 18 1 0 10 0.05 1 0.05 1 jdepend.swingui.PackageNode jdepend.swingui.AboutDialog jdepend.swingui.AboutDialog$1 jdepend.swingui.AboutDialog$2 jdepend.swingui.AfferentNode jdepend.swingui.DependTree jdepend.swingui.DependTreeModel jdepend.swingui.EfferentNode jdepend.swingui.JDepend jdepend.swingui.JDepend$1 jdepend.swingui.JDepend$2 jdepend.swingui.JDepend$3 jdepend.swingui.JDepend$4 jdepend.swingui.JDepend$5 jdepend.swingui.JDepend$6 jdepend.swingui.JDepend$AboutAction jdepend.swingui.JDepend$ExitAction jdepend.swingui.JDepend$TreeListener jdepend.swingui.StatusPanel java.awt java.awt.event java.io java.lang java.text java.util javax.swing javax.swing.event javax.swing.tree jdepend.framework 1 1 0 1 5 0 0.83 0.17 1 jdepend.textui.JDepend java.io java.lang java.text java.util jdepend.framework jdepend.xmlui 1 1 0 0 6 0 1 0 1 jdepend.xmlui.JDepend java.io java.lang java.text java.util jdepend.framework jdepend.textui No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. jdepend-2.9.1/docs/jdepend-report.dot0000644000000000000000000001021010236624040016203 0ustar rootroot digraph g { graph [ rankdir = "LR" ]; node [ fontsize = "12" fontname = "Courier" shape = "ellipse" ]; edge[]; "java.awt" [ label="java.awt | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.awt.event" [ label="java.awt.event | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.io" [ label="java.io | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.lang" [ label="java.lang | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.lang.reflect" [ label="java.lang.reflect | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.math" [ label="java.math | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.net" [ label="java.net | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.rmi" [ label="java.rmi | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.sql" [ label="java.sql | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.text" [ label="java.text | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.util" [ label="java.util | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.util.jar" [ label="java.util.jar | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "java.util.zip" [ label="java.util.zip | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "javax.swing" [ label="javax.swing | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "javax.swing.event" [ label="javax.swing.event | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "javax.swing.tree" [ label="javax.swing.tree | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "jdepend.framework" [ label="jdepend.framework | Total Classes: 35" shape="record" color=".99 0.07 .9" style=filled ]; "jdepend.framework" -> "java.io" "jdepend.framework" -> "java.lang" "jdepend.framework" -> "java.lang.reflect" "jdepend.framework" -> "java.math" "jdepend.framework" -> "java.net" "jdepend.framework" -> "java.rmi" "jdepend.framework" -> "java.sql" "jdepend.framework" -> "java.text" "jdepend.framework" -> "java.util" "jdepend.framework" -> "java.util.jar" "jdepend.framework" -> "java.util.zip" "jdepend.framework" -> "junit.framework" "jdepend.framework" -> "junit.textui" "jdepend.swingui" [ label="jdepend.swingui | Total Classes: 19" shape="record" color=".99 0.05 .9" style=filled ]; "jdepend.swingui" -> "java.awt" "jdepend.swingui" -> "java.awt.event" "jdepend.swingui" -> "java.io" "jdepend.swingui" -> "java.lang" "jdepend.swingui" -> "java.text" "jdepend.swingui" -> "java.util" "jdepend.swingui" -> "javax.swing" "jdepend.swingui" -> "javax.swing.event" "jdepend.swingui" -> "javax.swing.tree" "jdepend.swingui" -> "jdepend.framework" "jdepend.textui" [ label="jdepend.textui | Total Classes: 1" shape="record" color=".99 0.17 .9" style=filled ]; "jdepend.textui" -> "java.io" "jdepend.textui" -> "java.lang" "jdepend.textui" -> "java.text" "jdepend.textui" -> "java.util" "jdepend.textui" -> "jdepend.framework" "jdepend.xmlui" [ label="jdepend.xmlui | Total Classes: 1" shape="record" color=".99 0 .9" style=filled ]; "jdepend.xmlui" -> "java.io" "jdepend.xmlui" -> "java.lang" "jdepend.xmlui" -> "java.text" "jdepend.xmlui" -> "java.util" "jdepend.xmlui" -> "jdepend.framework" "jdepend.xmlui" -> "jdepend.textui" "junit.framework" [ label="junit.framework | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; "junit.textui" [ label="junit.textui | Total Classes: " shape="record" color=".99 0.0 .9" style=filled ]; } jdepend-2.9.1/docs/jdepend-report.txt0000644000000000000000000001063110236624040016243 0ustar rootroot -------------------------------------------------- - Package: jdepend.framework -------------------------------------------------- Stats: Total Classes: 35 Concrete Classes: 31 Abstract Classes: 4 Ca: 3 Ce: 2 A: 0.11 I: 0.4 D: 0.49 Abstract Classes: jdepend.framework.AbstractParser jdepend.framework.MockAbstractClass jdepend.framework.MockInterface jdepend.framework.ParserListener Concrete Classes: jdepend.framework.AllTests jdepend.framework.ClassFileParser jdepend.framework.ClassFileParser$AttributeInfo jdepend.framework.ClassFileParser$Constant jdepend.framework.ClassFileParser$FieldOrMethodInfo jdepend.framework.ClassFileParserTest jdepend.framework.CollectAllCyclesTest jdepend.framework.ComponentTest jdepend.framework.ConstraintTest jdepend.framework.CycleTest jdepend.framework.DependencyConstraint jdepend.framework.ExampleTest jdepend.framework.FileManager jdepend.framework.FileManagerTest jdepend.framework.FilterTest jdepend.framework.JDepend jdepend.framework.JDependTestCase jdepend.framework.JarFileParserTest jdepend.framework.JavaClass jdepend.framework.JavaClass$ClassComparator jdepend.framework.JavaClassBuilder jdepend.framework.JavaClassBuilder$1 jdepend.framework.JavaPackage jdepend.framework.MetricTest jdepend.framework.MockConcreteClass jdepend.framework.MockConcreteClass$MockInnerClass jdepend.framework.MockPackageClass jdepend.framework.PackageComparator jdepend.framework.PackageFilter jdepend.framework.PropertyConfigurator jdepend.framework.PropertyConfiguratorTest Depends Upon: junit.framework junit.textui Used By: jdepend.swingui jdepend.textui jdepend.xmlui -------------------------------------------------- - Package: jdepend.swingui -------------------------------------------------- Stats: Total Classes: 19 Concrete Classes: 18 Abstract Classes: 1 Ca: 0 Ce: 1 A: 0.05 I: 1 D: 0.05 Abstract Classes: jdepend.swingui.PackageNode Concrete Classes: jdepend.swingui.AboutDialog jdepend.swingui.AboutDialog$1 jdepend.swingui.AboutDialog$2 jdepend.swingui.AfferentNode jdepend.swingui.DependTree jdepend.swingui.DependTreeModel jdepend.swingui.EfferentNode jdepend.swingui.JDepend jdepend.swingui.JDepend$1 jdepend.swingui.JDepend$2 jdepend.swingui.JDepend$3 jdepend.swingui.JDepend$4 jdepend.swingui.JDepend$5 jdepend.swingui.JDepend$6 jdepend.swingui.JDepend$AboutAction jdepend.swingui.JDepend$ExitAction jdepend.swingui.JDepend$TreeListener jdepend.swingui.StatusPanel Depends Upon: jdepend.framework Used By: Not used by any packages. -------------------------------------------------- - Package: jdepend.textui -------------------------------------------------- Stats: Total Classes: 1 Concrete Classes: 1 Abstract Classes: 0 Ca: 1 Ce: 1 A: 0 I: 0.5 D: 0.5 Abstract Classes: Concrete Classes: jdepend.textui.JDepend Depends Upon: jdepend.framework Used By: jdepend.xmlui -------------------------------------------------- - Package: jdepend.xmlui -------------------------------------------------- Stats: Total Classes: 1 Concrete Classes: 1 Abstract Classes: 0 Ca: 0 Ce: 2 A: 0 I: 1 D: 0 Abstract Classes: Concrete Classes: jdepend.xmlui.JDepend Depends Upon: jdepend.framework jdepend.textui Used By: Not used by any packages. -------------------------------------------------- - Package: junit.framework -------------------------------------------------- No stats available: package referenced, but not analyzed. -------------------------------------------------- - Package: junit.textui -------------------------------------------------- No stats available: package referenced, but not analyzed. -------------------------------------------------- - Package Dependency Cycles: -------------------------------------------------- -------------------------------------------------- - Summary: -------------------------------------------------- Name, Class Count, Abstract Class Count, Ca, Ce, A, I, D, V: jdepend.framework,35,4,3,2,0.11,0.4,0.49,1 jdepend.swingui,19,1,0,1,0.05,1,0.05,1 jdepend.textui,1,0,1,1,0,0.5,0.5,1 jdepend.xmlui,1,0,0,2,0,1,0,1 junit.framework,0,0,1,0,0,0,1,1 junit.textui,0,0,1,0,0,0,1,1 jdepend-2.9.1/docs/jdepend-xml.out0000644000000000000000000001276410236624040015531 0ustar rootroot 2 2 0 0 4 0 1 0 ABCGatewayAdapter XYZGatewayAdapter com.abc.epayment com.xyz.epayment epayment.framework epayment.response 5 5 0 0 1 0 1 0 AuthorizeCommand CaptureCommand CreditCommand SaleCommand VoidSaleCommand epayment.framework 6 1 5 5 0 0.83 0 0.17 AbstractPaymentCommand IGatewayAdapter IPaymentCommand IPaymentRequest IPaymentResponse PaymentException epayment.adapters epayment.commands epayment.processor epayment.request epayment.response 2 2 0 0 1 0 1 0 PaymentProcessor PaymentProcessorConfigurator epayment.framework 1 1 0 0 1 0 1 0 PaymentRequest epayment.framework 1 1 0 1 1 0 0.5 0.5 PaymentResponse epayment.framework epayment.adapters No stats available: package referenced, but not analyzed. No stats available: package referenced, but not analyzed. jdepend-2.9.1/sample/0000755000000000000000000000000010236624042013112 5ustar rootrootjdepend-2.9.1/sample/epayment/0000755000000000000000000000000010236624042014734 5ustar rootrootjdepend-2.9.1/sample/epayment/framework/0000755000000000000000000000000010236624042016731 5ustar rootrootjdepend-2.9.1/sample/epayment/framework/PaymentException.java0000644000000000000000000000111210236624042023063 0ustar rootrootpackage epayment.framework; /** * The PaymentException class is an * Exception thrown when a payment * processing error occurs. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class PaymentException extends Exception { /** * Constructs a PaymentException with * the specified message. * * @param message Message. */ public PaymentException(String message) { super (message); } } jdepend-2.9.1/sample/epayment/framework/IPaymentRequest.java0000644000000000000000000000240510236624040022672 0ustar rootrootpackage epayment.framework; import java.io.Serializable; /** * The IPaymentRequest interface defines * the interface for payment request information. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public interface IPaymentRequest extends Serializable { /** * Sets the user id. * * @param id User id. */ public void setUserId(String id); /** * Sets the user password. * * @param password User password. */ public void setUserPassword(String password); /** * Sets the cardholder name. * * @param name Cardholder name. */ public void setAccountName(String name); /** * Sets the cardholder's account number. *

* This number will be stripped of all spaces, * non-numeric characters, and dashes. * * @param number Card account number. */ public void setAccountNumber(String number); /** * Sets the amount of the transaction. *

* The format is xxx.yy. * * @param amount Amount in dollars. */ public void setAmount(double amount); /** * Sets the reporting comment. * * @param comment Reporting comment. */ public void setComment(String comment); } jdepend-2.9.1/sample/epayment/framework/AbstractPaymentCommand.java0000644000000000000000000000213110236624040024167 0ustar rootrootpackage epayment.framework; /** * The AbstractPaymentCommand class provides * the default behavior for the IPaymentCommand * interface. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public abstract class AbstractPaymentCommand implements IPaymentCommand { private IPaymentRequest _request; /** * Constructs an AbstractPaymentCommand * instance. */ public AbstractPaymentCommand(IPaymentRequest request) { _request = request; } /** * Executes this command using the specified payment * adapter and returns a payment response. * * @param adapter Payment adapter. * @return response Payment response. * @throws PaymentException If an error occurs. */ public abstract IPaymentResponse execute(IGatewayAdapter adapter) throws PaymentException; /** * Returns the payment request. * * @return Payment request. */ protected IPaymentRequest getPaymentRequest() { return _request; } } jdepend-2.9.1/sample/epayment/framework/IPaymentResponse.java0000644000000000000000000000120310236624040023033 0ustar rootrootpackage epayment.framework; import java.io.Serializable; /** * The IPaymentResponse interface defines * the interface for payment response information. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public interface IPaymentResponse extends Serializable { /** * Returns the processed date. * * @return Processed date. */ public String getProcessedDate(); /** * Returns the response message. * * @return Response message. */ public String getResponseMessage(); } jdepend-2.9.1/sample/epayment/framework/IPaymentCommand.java0000644000000000000000000000175410236624040022626 0ustar rootrootpackage epayment.framework; /** * The IPaymentCommand interface defines * the common interface for all electronic payment * actions. *

* Implementors of this interface encapsulate a payment * request as an object which can be generically * processed by the PaymentProcessor. * The PaymentProcessor is responsible * for installing an appropriate implementation of * an IGatewayAdapter. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public interface IPaymentCommand { /** * Executes this command using the specified payment * adapter and returns a payment response. * * @param adapter Payment adapter. * @return response Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse execute(IGatewayAdapter adapter) throws PaymentException; } jdepend-2.9.1/sample/epayment/framework/IGatewayAdapter.java0000644000000000000000000000430210236624040022604 0ustar rootrootpackage epayment.framework; /** * The IGatewayAdapter interface defines * the common interface for all electronic payment * gateways. *

* Implementors of this interface serve as interface * adapters to vendor-specific payment gateways. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public interface IGatewayAdapter { /** * Sets the payment gateway host. * * @param host Gateway host. */ public void setHost(String host); /** * Performs an authorizes for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse authorize(IPaymentRequest request) throws PaymentException; /** * Performs a capture for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse capture(IPaymentRequest request) throws PaymentException; /** * Performs a sale (authorize and capture) for the specified * payment request information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse sale(IPaymentRequest request) throws PaymentException; /** * Performs a credit for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse credit(IPaymentRequest request) throws PaymentException; /** * Performs a void for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse voidSale(IPaymentRequest request) throws PaymentException; } jdepend-2.9.1/sample/epayment/commands/0000755000000000000000000000000010236624042016535 5ustar rootrootjdepend-2.9.1/sample/epayment/commands/AuthorizeCommand.java0000644000000000000000000000200010236624040022637 0ustar rootrootpackage epayment.commands; import epayment.framework.*; /** * The AuthorizeCommand class is an * AbstractPaymentCommand for authorizing * a purchase. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class AuthorizeCommand extends AbstractPaymentCommand { /** * Constructs an AuthorizeCommand with * the specified payment request. * * @param request Payment request. */ public AuthorizeCommand(IPaymentRequest request) { super(request); } /** * Executes this command using the specified payment * adapter and returns a payment response. * * @param adapter Payment adapter. * @return response Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse execute(IGatewayAdapter adapter) throws PaymentException { return adapter.authorize(getPaymentRequest()); } } jdepend-2.9.1/sample/epayment/commands/CaptureCommand.java0000644000000000000000000000201010236624042022273 0ustar rootrootpackage epayment.commands; import epayment.framework.*; /** * The CaptureCommand class is an * AbstractPaymentCommand for capturing * a previously authorized amount. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class CaptureCommand extends AbstractPaymentCommand { /** * Constructs an CaptureCommand with * the specified payment request. * * @param request Payment request. */ public CaptureCommand(IPaymentRequest request) { super(request); } /** * Executes this command using the specified payment * adapter and returns a payment response. * * @param adapter Payment adapter. * @return response Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse execute(IGatewayAdapter adapter) throws PaymentException { return adapter.capture(getPaymentRequest()); } } jdepend-2.9.1/sample/epayment/commands/SaleCommand.java0000644000000000000000000000201710236624042021563 0ustar rootrootpackage epayment.commands; import epayment.framework.*; /** * The SaleCommand class is an * AbstractPaymentCommand for authorizing * and capturing a purchase in an * atomic operation. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class SaleCommand extends AbstractPaymentCommand { /** * Constructs an SaleCommand with * the specified payment request. * * @param request Payment request. */ public SaleCommand(IPaymentRequest request) { super(request); } /** * Executes this command using the specified payment * adapter and returns a payment response. * * @param adapter Payment adapter. * @return response Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse execute(IGatewayAdapter adapter) throws PaymentException { return adapter.sale(getPaymentRequest()); } } jdepend-2.9.1/sample/epayment/commands/VoidSaleCommand.java0000644000000000000000000000177410236624040022414 0ustar rootrootpackage epayment.commands; import epayment.framework.*; /** * The VoidSaleCommand class is an * AbstractPaymentCommand for voiding * a previous sale. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class VoidSaleCommand extends AbstractPaymentCommand { /** * Constructs an VoidSaleCommand with * the specified payment request. * * @param request Payment request. */ public VoidSaleCommand(IPaymentRequest request) { super(request); } /** * Executes this command using the specified payment * adapter and returns a payment response. * * @param adapter Payment adapter. * @return response Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse execute(IGatewayAdapter adapter) throws PaymentException { return adapter.voidSale(getPaymentRequest()); } } jdepend-2.9.1/sample/epayment/commands/CreditCommand.java0000644000000000000000000000176710236624042022124 0ustar rootrootpackage epayment.commands; import epayment.framework.*; /** * The CreditCommand class is an * AbstractPaymentCommand for crediting * a previous capture. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class CreditCommand extends AbstractPaymentCommand { /** * Constructs an CreditCommand with * the specified payment request. * * @param request Payment request. */ public CreditCommand(IPaymentRequest request) { super(request); } /** * Executes this command using the specified payment * adapter and returns a payment response. * * @param adapter Payment adapter. * @return response Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse execute(IGatewayAdapter adapter) throws PaymentException { return adapter.credit(getPaymentRequest()); } } jdepend-2.9.1/sample/epayment/adapters/0000755000000000000000000000000010236624040016535 5ustar rootrootjdepend-2.9.1/sample/epayment/adapters/ABCGatewayAdapter.java0000644000000000000000000000766010236624042022623 0ustar rootrootpackage epayment.adapters; import epayment.adapters.*; import epayment.framework.IGatewayAdapter; import epayment.framework.IPaymentRequest; import epayment.framework.IPaymentResponse; import epayment.framework.PaymentException; import epayment.response.PaymentResponse; /** * The ABCGatewayAdapter class is an * IGatewayAdapter which adapts * to a vendor-specific epayment package. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class ABCGatewayAdapter implements IGatewayAdapter { // // Vendor-specific proxy class. // //private ABCProxy _proxy; /** * Constructs an ABCGatewayAdapter instance. */ public ABCGatewayAdapter() { //_proxy = new ABCProxy(); } /** * Sets the payment gateway host. * * @param host Gateway host. */ public void setHost(String host) { //_proxy.setGatewayHostName(host); } /** * Performs an authorize for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse authorize(IPaymentRequest request) throws PaymentException { PaymentResponse response = new PaymentResponse(); // // Adapt the request information to the // vendor-specific proxy API. // /* _proxy.setAction("authorize"); _proxy.setUserId(request.getUserId()); _proxy.setPassword(request.getUserPassword()); _proxy.setAccountHolderName(request.getAccountName()); _proxy.setAccountHolderNumber(request.getAccountNumber()); _proxy.setUserDefinedField1(request.getComment()); _proxy.setTransactionAmount(request.getAmount()); */ // // Perform the transaction against // the vendor-specific API. // /* boolean success = false; try { success = _proxy.performTransaction(); } catch (Exception e) { throw new PaymentException(e.getMessage()); } */ // // Adapt the vendor-specific response information // to the generic response API. // /* if (success) { response.setResponseMessage(_proxy.getResult()); response.setProcessedDate(_proxy.getDate()); } else { throw new PaymentException(_proxy.getResult()); } */ return response; } /** * Performs a capture for the specified payment * request information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse capture(IPaymentRequest request) throws PaymentException { // similar to authorize() return new PaymentResponse(); } /** * Performs a sale (authorize and capture) for the specified * payment request information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse sale(IPaymentRequest request) throws PaymentException { // similar to authorize() return new PaymentResponse(); } /** * Performs a credit for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse credit(IPaymentRequest request) throws PaymentException { // similar to authorize() return new PaymentResponse(); } /** * Performs a void for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse voidSale(IPaymentRequest request) throws PaymentException { // similar to authorize() return new PaymentResponse(); } } jdepend-2.9.1/sample/epayment/adapters/XYZGatewayAdapter.java0000644000000000000000000000752110236624040022722 0ustar rootrootpackage epayment.adapters; import epayment.framework.IGatewayAdapter; import epayment.framework.IPaymentRequest; import epayment.framework.IPaymentResponse; import epayment.framework.PaymentException; import epayment.response.PaymentResponse; /** * The XYZGatewayAdapter class is an * IGatewayAdapter which adapts * to a vendor-specific epayment package. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class XYZGatewayAdapter implements IGatewayAdapter { // // Vendor-specific proxy class. // //private XYZProxy _proxy; /** * Constructs an XYZGatewayAdapter instance. */ public XYZGatewayAdapter() { //_proxy = new XYZProxy(); } /** * Sets the payment gateway host. * * @param host Gateway host. */ public void setHost(String host) { //_proxy.setHostName(host); } /** * Performs an authorize for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse authorize(IPaymentRequest request) throws PaymentException { PaymentResponse response = new PaymentResponse(); // // Adapt the request information to the // vendor-specific proxy API. // /* _proxy.setAction("1"); _proxy.setUser(request.getUserId()); _proxy.setPass(request.getUserPassword()); _proxy.setName(request.getAccountName()); _proxy.setNumber(request.getAccountNumber()); _proxy.setComment(request.getComment()); _proxy.setAmount(request.getAmount()); */ // // Perform the transaction against // the vendor-specific API. // /* boolean success = false; try { success = _proxy.execute(); } catch (Exception e) { throw new PaymentException(e.getMessage()); } */ // // Adapt the vendor-specific response information // to the generic response API. // /* if (success) { response.setResponseMessage(_proxy.getExecutionResult()); response.setProcessedDate(_proxy.getDateTime()); } else { throw new PaymentException(_proxy.getResult()); } */ return response; } /** * Performs a capture for the specified payment * request information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse capture(IPaymentRequest request) throws PaymentException { // similar to authorize() return new PaymentResponse(); } /** * Performs a sale (authorize and capture) for the specified * payment request information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse sale(IPaymentRequest request) throws PaymentException { // similar to authorize() return new PaymentResponse(); } /** * Performs a credit for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse credit(IPaymentRequest request) throws PaymentException { // similar to authorize() return new PaymentResponse(); } /** * Performs a void for the specified payment request * information and returns a payment response. * * @param request Payment request. * @return Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse voidSale(IPaymentRequest request) throws PaymentException { // similar to authorize() return new PaymentResponse(); } } jdepend-2.9.1/sample/epayment/response/0000755000000000000000000000000010236624042016572 5ustar rootrootjdepend-2.9.1/sample/epayment/response/PaymentResponse.java0000644000000000000000000000316710236624042022600 0ustar rootrootpackage epayment.response; import epayment.framework.IPaymentResponse; /** * The PaymentResponse class is an * IPaymentResponse that encapsulates * the basic payment response information. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class PaymentResponse implements IPaymentResponse { private String _processedDate; private String _responseMessage; /** * Constructs a PaymentResponse * with default values. */ public PaymentResponse() { _processedDate = ""; _responseMessage = ""; } /** * Returns the processed date. * * @return Processed date. */ public String getProcessedDate() { return _processedDate; } /** * Sets the processed date. * * @param date Processed date. */ protected void setProcessedDate(String date) { _processedDate = date; } /** * Returns the response message. * * @return Response message. */ public String getResponseMessage() { return _responseMessage; } /** * Sets the response message. * * @param message Response message. */ protected void setResponseMessage(String message) { _responseMessage = message; } /** * Returns the string representation of this object. * * @return String representation. */ public String toString() { StringBuffer contents = new StringBuffer(); contents.append("Response Message = " + _responseMessage + "\n"); contents.append("Processed Date = " + _processedDate + "\n"); return contents.toString(); } } jdepend-2.9.1/sample/epayment/request/0000755000000000000000000000000010236624040016422 5ustar rootrootjdepend-2.9.1/sample/epayment/request/PaymentRequest.java0000644000000000000000000000565710236624040022270 0ustar rootrootpackage epayment.request; import epayment.framework.IPaymentRequest; /** * The PaymentRequest class is an * IPaymentRequest that encapsulates * the basic payment request information. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class PaymentRequest implements IPaymentRequest { private String _userId; private String _userPassword; private String _name; private String _accountNumber; private double _amount; private String _comment; /** * Constructs a PaymentRequest. * with default values. */ public PaymentRequest() { _userId = ""; _userPassword = ""; _name = ""; _accountNumber = ""; _amount = 0.0; _comment = ""; } /** * Sets the user id. * * @param id User id. */ public void setUserId(String id) { _userId = id; } /** * Returns the user id. * * @return User id. */ protected String getUserId() { return _userId; } /** * Sets the user password. * * @param password User password. */ public void setUserPassword(String password) { _userPassword = password; } /** * Returns the user password. * * @return User password. */ protected String getUserPassword() { return _userPassword; } /** * Sets the name. * * @param name Name. */ public void setAccountName(String name) { _name = name; } /** * Returns the name. * * @return Name. */ protected String getAccountName() { return _name; } /** * Sets the account number. * * @param number Account number. */ public void setAccountNumber(String number) { _accountNumber = number; } /** * Returns the account number. * * @return Account number. */ protected String getAccountNumber() { return _accountNumber; } /** * Sets the amount of the transaction. * * @param amount Amount in dollars. */ public void setAmount(double amount) { _amount = amount; } /** * Returns the amount of the transaction. * * @return Amount in dollars. */ protected double getAmount() { return _amount; } /** * Sets the reporting comment. * * @param comment Reporting comment. */ public void setComment(String comment) { _comment = comment; } /** * Returns the reporting comment. * * @return Reporting comment. */ protected String getComment() { return _comment; } /** * Returns the string representation of this object. * * @return String representation. */ public String toString() { StringBuffer contents = new StringBuffer(); contents.append("User ID = " + _userId + "\n"); contents.append("User Password = " + _userPassword + "\n"); contents.append("Name = " + _name + "\n"); contents.append("Account Number = " + _accountNumber + "\n"); contents.append("Amount = " + _amount + "\n"); return contents.toString(); } } jdepend-2.9.1/sample/epayment/processor/0000755000000000000000000000000010236624042016753 5ustar rootrootjdepend-2.9.1/sample/epayment/processor/PaymentProcessor.java0000644000000000000000000000425710236624040023141 0ustar rootrootpackage epayment.processor; import epayment.framework.IGatewayAdapter; import epayment.framework.IPaymentCommand; import epayment.framework.IPaymentResponse; import epayment.framework.PaymentException; /** * The PaymentProcessor class is a bridge * for an IGatewayAdapter. This class is * responsible for processing IPaymentCommand * instances, while decoupling them from specific * payment processing implementations. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class PaymentProcessor { private IGatewayAdapter _adapter; private static PaymentProcessor _processor; /** * Constructs a PaymentProcessor * instance using the default configurator. */ public PaymentProcessor() { try { PaymentProcessorConfigurator configurator = new PaymentProcessorConfigurator(); configurator.configure(this); } catch(Exception e) { System.err.println("Payment processor configuration error: " + e.getMessage()); // default to consistent state } } /** * Constructs a PaymentProcessor * instance with the specified gateway adapter. * * @param adapter Gateway adapter. */ public PaymentProcessor(IGatewayAdapter adapter) { setGatewayAdapter(adapter); } /** * Returns the sole instance of this class. * * @return Payment processor. */ public static PaymentProcessor getProcessor() { if (_processor == null) { _processor = new PaymentProcessor(); } return _processor; } /** * Sets the gateway adapter. * * @param adapter Gateway adapter. */ protected void setGatewayAdapter(IGatewayAdapter adapter) { _adapter = adapter; } /** * Processes the specified payment command using * the specified payment request and returns a * payment response. * * @param command Payment command. * @return response Payment response. * @throws PaymentException If an error occurs. */ public IPaymentResponse process(IPaymentCommand command) throws PaymentException { return command.execute(_adapter); } } jdepend-2.9.1/sample/epayment/processor/PaymentProcessorConfigurator.java0000644000000000000000000000216610236624042025523 0ustar rootrootpackage epayment.processor; import epayment.framework.IGatewayAdapter; /** * The PaymentProcessorConfigurator class * is responsible for configuring the run-time * environment of the PaymentProcessor. *

* This class is strictly an example. * * @author Mike Clark * @author Clarkware Consulting */ public class PaymentProcessorConfigurator { /** * Constructs a PaymentProcessorConfigurator. */ public PaymentProcessorConfigurator() { } /** * Configures the specified payment processor. * * @param processor Payment processor to configure. * @throws IOException If a configuration error occurred. */ public void configure(PaymentProcessor processor) { // // Production applications should use a dynamic // configuration mechanism with an adapter factory // to construct the appropriate adapter. // IGatewayAdapter adapter = null; /* adapter = makeAdapter("XYZGatewayAdapter"); adapter.setHost(someHostName); */ processor.setGatewayAdapter(adapter); } } jdepend-2.9.1/sample/jdepend.properties0000644000000000000000000000037010236624042016641 0ustar rootroot# # JDepend Properties # # # Package filters # ignore.java=java.*,javax.* ignore.sun=sun.*,com.sun.* ignore.tests=com.xyz.tests # # Preset Volatility (V) # com.xyz.a.neverchanges=0 # # Disable analyzing inner classes # analyzeInnerClasses=false jdepend-2.9.1/build.xml0000644000000000000000000001604710236624040013460 0ustar rootroot Builds and tests JDepend - the Java package dependency analyzer.