Compare commits

...

110 Commits

Author SHA1 Message Date
Diomidis Spinellis e83df07d5f
Merge pull request #65 from VillePekka/patch-1
Fix typo in README.md
2025-12-01 00:30:52 +02:00
VillePekka e79f81666b
Fix typo in README.md
Comparisson => Comparison
2025-11-30 23:19:24 +01:00
Diomidis Spinellis 893fa38908
Add D2 and comparison links 2023-10-27 13:33:55 +03:00
Diomidis Spinellis a4fa650471
Add related tools 2023-06-13 15:23:31 +03:00
Diomidis Spinellis 606976778e [maven-release-plugin] prepare for next development iteration 2023-05-23 14:59:36 +03:00
Diomidis Spinellis 8d7a3e4b5c [maven-release-plugin] prepare release R6_0_0 2023-05-23 14:59:31 +03:00
Diomidis Spinellis 2a471e5b8c
Merge pull request #64 from laurentschoelens/java9
jdk9 migration fixes
2023-04-08 20:58:59 +03:00
Laurent SCHOELENS 42c648b596 fix findClass for UMLNoteOptions / UMLOptions unqualified classes 2023-03-28 18:58:28 +02:00
Laurent SCHOELENS 5a058a3ace more readable else if statement 2023-03-28 18:58:20 +02:00
Laurent SCHOELENS 24e5822d7b extra fix for typeparameters in classes 2023-03-28 13:14:18 +02:00
Laurent SCHOELENS 7147eaa5ed fix simpleName v. qualifiedName for packageProccesing 2023-03-28 10:48:09 +02:00
Diomidis Spinellis 62acb7337b
Merge pull request #63 from laurentschoelens/java9
jdk9 : bugfixes and update readme
2023-03-27 17:53:37 +03:00
Laurent SCHOELENS de056154bd remove reporter diagnostic / fix class graph / make javase api 9 default / fix package-list and element-list api fetch 2023-03-27 14:52:04 +02:00
Laurent SCHOELENS 27d7821666 fix generation with primitive array 2023-03-27 12:31:35 +02:00
Laurent SCHOELENS 16c1937aad update readme 2023-03-27 12:24:31 +02:00
Laurent SCHOELENS 70929da1d0 make some fixes after run on bigger project 2023-03-27 12:18:46 +02:00
Diomidis Spinellis 6115e12837
Merge pull request #62 from laurentschoelens/java9
jdk9 port of UMLGraph
2023-03-24 17:57:20 +02:00
Laurent SCHOELENS d273b6a3ef fix junit dep / jdk11+ build 2023-03-24 16:11:29 +01:00
Laurent SCHOELENS cd8c3629a1 version running jdk9 2023-03-24 14:55:50 +01:00
Laurent SCHOELENS c8f805bdef reformat classes 2023-03-21 09:15:55 +01:00
Laurent SCHOELENS d80597d547 remove .classpath / .project files and add it to .gitignore 2023-03-21 08:15:34 +01:00
Diomidis Spinellis 09576db5ae Merge branch 'master' of github.com:dspinellis/UMLGraph 2019-03-25 22:17:17 +02:00
Diomidis Spinellis 75cc871a10 Correct version extraction when tags are missing
Issue: #55
2019-03-25 22:16:02 +02:00
Erich Schubert 0967a91289 Add -hideprivateinner option 2018-11-03 23:06:36 +01:00
Erich Schubert 0ba1798ac5 Point out jitpack.io option to get jars. 2018-11-03 21:45:04 +01:00
Erich Schubert bab25cbe35 invalid xml 2018-11-03 20:41:56 +01:00
Diomidis Spinellis 26c9f9d1e5
Merge pull request #54 from kno10/java8
Larger refactorings
2018-11-01 22:38:46 +02:00
Erich Schubert e93b793bd6 Get rid of these margins, then we don't need port="p" anymore. 2018-10-28 13:34:16 +01:00
Erich Schubert e27eeb4bc3 Simplify classinfo handling. 2018-10-27 23:23:47 +02:00
Erich Schubert 867dec5d9c fixup dot formatting 2018-10-27 23:23:47 +02:00
Erich Schubert 1d03695f8e Produce simpler dot files, reduce code duplication in edge generation. 2018-10-27 23:23:47 +02:00
Erich Schubert 8b39c4614f Improve node naming of inner classes. 2018-10-27 23:23:46 +02:00
Erich Schubert 7169d40228 Add -hideGenerics option. 2018-10-27 23:23:46 +02:00
Erich Schubert dc18c503e9 Improve class info handling. 2018-10-27 23:23:46 +02:00
Erich Schubert c7d8648352 Cleanup classToUrl 2018-10-27 23:18:32 +02:00
Erich Schubert aa15be7405 Determine context package only once. 2018-10-27 23:18:32 +02:00
Erich Schubert 1925d2f1c7 More StringUtil functionality. 2018-10-27 23:18:32 +02:00
Erich Schubert 08b8976076 Caching is not necessary with current JavaDoc (8, maybe even earlier) 2018-10-27 23:18:31 +02:00
Erich Schubert 1b29f70460 Avoid having to add/remove hyphens for all options. 2018-10-27 23:18:31 +02:00
Erich Schubert 2f27948475 Refactor font handling. 2018-10-27 23:18:31 +02:00
Erich Schubert 7d9f665d07 Refactor shape into enum pattern. 2018-10-27 23:18:31 +02:00
Erich Schubert 9ddf84129a Move visibility symbols into Visibility class. 2018-10-27 23:18:31 +02:00
Erich Schubert a4ab6f179a Have relation styles in a single place. 2018-10-27 23:18:31 +02:00
Erich Schubert fe2c0c3df1 Streamline code, smaller optimizations. 2018-10-27 23:18:31 +02:00
Erich Schubert f3e945c646 Remove warning in code obsoleted by commit #a29ba215 2018-10-27 23:08:20 +02:00
Erich Schubert 141c8a9353 Trivial simplification. 2018-10-27 21:30:17 +02:00
Erich Schubert fc1b199daf Better error reporting. 2018-10-27 21:30:17 +02:00
Erich Schubert 1e52483a86 Postpone test failues, to first generate the pngs 2018-10-27 21:30:17 +02:00
Erich Schubert f1be5aaee8 add 'clean' ant target 2018-10-27 21:30:17 +02:00
Erich Schubert f7df826f53 fix broken test, where undeclared package was lost previously, now preserved 2018-10-27 21:30:17 +02:00
Erich Schubert 644d148455 Exit code on errors. 2018-10-27 21:30:17 +02:00
Erich Schubert e51f53b25e Add -qualifyGenerics to optionLength. 2018-10-26 21:17:21 +02:00
Erich Schubert a29ba21580 Fix active class shape broken by commit 1b4c9763 + add test.
This was easy to break, because of a non-obvious logic.

Instead we now use the hack of just using a too large rowspan.
2018-10-26 01:32:31 +02:00
Erich Schubert bca0ceae17 Cleanup Options: move defaults to declaration rather than constructor. 2018-10-25 00:18:28 +02:00
Erich Schubert 71f74d3093 Move some basic string processing helpers into StringUtil. 2018-10-25 00:18:28 +02:00
Erich Schubert 1b4c97630d Old merge error / duplicated line? 2018-10-25 00:18:28 +02:00
Erich Schubert 477d5cc58a Fail on test failures. 2018-10-25 00:18:28 +02:00
Diomidis Spinellis e5bc6f1f8f Exit with an error on structural differences 2018-10-24 13:34:33 +03:00
Diomidis Spinellis e2595350fd Correct build status icon URL 2018-10-24 13:11:59 +03:00
Diomidis Spinellis 8806b89cd8 Do not set OS type
This avoids the following error java.lang.Runtime.exec:
java.lang.Error: generic is not a supported OS platform.
2018-10-24 13:11:59 +03:00
Diomidis Spinellis 70a7580e2c Install GraphViz as a CI dependency 2018-10-24 12:52:55 +03:00
Diomidis Spinellis cb77d617e9 Remove unneeded deps 2018-10-24 12:47:57 +03:00
Diomidis Spinellis 13bb2d54bc Remove confusing duplicate file 2018-10-24 12:47:11 +03:00
Diomidis Spinellis 27baa4a6be Add Travis CI configuration 2018-10-24 12:45:09 +03:00
Diomidis Spinellis 3eb6f8d034 Convert README into markdown 2018-10-24 12:45:09 +03:00
Diomidis Spinellis b5238b3bdc
Merge pull request #52 from kno10/patch-qualify-generics
add -!qualifyGenerics option that strips package names only in generics
2018-10-24 12:25:55 +03:00
Erich Schubert 0477f4b82d add -!qualifyGenerics option that strips package names only in generics
This is useful in combination with `-qualify`;
in particular with `-qualify -postfixpackage`

This version also supports *inner* classes, where the outer class has a
generic.

Test case: `p1.Class<A extends g1.G>.Inner<B super g2.G>`

Depending on `-qualify` and `-qualifyGenerics` this can become either:
```
p1.Class<A extends g1.G>.Inner<B super g2.G>
p1.Class<A extends G>.Inner<B super G>
Class<A extends g1.G>.Inner<B super g2.G>
Class<A extends G>.Inner<B super G>
```
on the long run, it may however be convenient to also allow hiding
generics completely, and/or show them just as diamonds. For example
`Class<>.Inner<>` as a shorthand. Other users will prefer to see the
constraint only, e.g., `Class<G>.Inner<G>`... it may need a list of
different named formatters.
2018-10-24 10:55:35 +02:00
Diomidis Spinellis 5de652cfeb
Merge pull request #53 from kno10/patch-includes
Add an @opt include option for the package view.
2018-10-23 23:33:01 +03:00
Erich Schubert 0e69b7a40f Add an @opt include option for the package view. 2018-10-21 03:38:40 +02:00
Diomidis Spinellis 132f389bcf
Merge pull request #50 from kno10/patch-4
Avoid repeated lowercasing
2018-08-14 14:32:09 +03:00
Diomidis Spinellis 7cc92e6fa2
Merge pull request #49 from kno10/patch-3
Strip generics from parent classes properly, fixes #20
2018-03-28 17:24:36 +03:00
Erich Schubert 40b24774eb Strip generics from parent classes properly
Fixes the handling of non-static inner classes `Parent<A>.Child` if the parent has generics, #20
2018-03-28 16:04:44 +02:00
Erich Schubert 021dc34d8e Avoid repeated lowercasing 2018-03-28 16:03:15 +02:00
Diomidis Spinellis 5cd82f641e
Merge pull request #48 from kno10/patch-1
Remove -verbose2 from docs
2018-03-28 15:47:38 +03:00
Erich Schubert ce3847a1e6
Remove -verbose2 from docs
According to the changelog, this option was removed.
2018-03-26 17:56:51 +02:00
Diomidis Spinellis 40b5a687cc Merge branch 'master' and update test data
To match the new -!autosize parameter.
2017-03-21 19:53:36 +02:00
Diomidis Spinellis c0b7962170 Update test data due to JavaDoc changes
From javadoc 1.8.0_20 to 1.8.0_121
2017-03-21 19:48:49 +02:00
Diomidis Spinellis d744535438 Merge pull request #45 from robross0606/master
Added "-autosize" parameter and fixed parameter matching bug with "!"
2017-03-21 19:47:26 +02:00
Robert Ross 160a7db3a7 Added "-autosize" parameter and fixed parameter matching bug with "!" 2017-03-21 13:20:15 -04:00
Diomidis Spinellis 5e854d5667 Merge pull request #43 from adrianN/patch-1
Update index.html
2017-03-15 17:49:19 +02:00
Adrian Neumann 962ad5af72 Update index.html
fix typo
2017-03-15 16:46:24 +01:00
Diomidis Spinellis e307530d8e Correct UMLGraph location 2016-10-24 20:38:25 +03:00
Diomidis Spinellis 6211164ca2 Merge pull request #34 from gousiosg/patch-1
Update documentation
2016-09-20 17:07:34 +03:00
Georgios Gousios 37dc189a29 s/SQO-OSS/Alitheia Core/
Also, add link to the annotated source code.
2016-09-20 15:05:14 +02:00
Diomidis Spinellis d0ede46da8 Correct URL 2016-09-16 23:47:03 +03:00
Diomidis Spinellis 30a611ec91 Update project web page location 2016-09-16 23:38:47 +03:00
Diomidis Spinellis a72c88fb70 Running testupdate requires bash 2016-09-16 23:34:03 +03:00
Diomidis Spinellis 09fab1724d Add reference to textual UML tool survey 2016-06-09 08:10:13 +03:00
Diomidis Spinellis db1a918e16 Remove repeated @override 2016-06-07 17:23:40 +03:00
Diomidis Spinellis ff13af7ea6 Merge pull request #32 from DevFactory/release/remove-dead-stores-fix-1
[squid:S1854] Dead stores should be removed
2016-06-07 17:22:20 +03:00
Diomidis Spinellis c4713960af Merge pull request #31 from DevFactory/release/replace-synchronized-classes-fix-1
[squid:S1149] Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used
2016-06-07 17:21:55 +03:00
Diomidis Spinellis a0ed8a2672 Merge pull request #30 from DevFactory/release/add-missing-override-annotation-fix-1
[squid:S1161] "@Override" annotation should be used on any method overriding (since Java 5) or implementing (since Java 6) another one
2016-06-07 17:21:36 +03:00
Diomidis Spinellis c4f32a5a74 Update test reference files 2016-06-07 17:20:48 +03:00
Diomidis Spinellis 86574a7824 Update Sun to Oracle URLs 2016-06-07 16:41:55 +03:00
Diomidis Spinellis 4425596017 Merge branch 'master' of github.com:dspinellis/UMLGraph 2016-06-07 16:10:47 +03:00
ayman abdelghany 1ec3be2f98 [squid:S1149] Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used 2016-06-07 14:12:05 +02:00
ayman abdelghany 105db10e1a [squid:S1854] Dead stores should be removed 2016-06-07 14:07:16 +02:00
ayman abdelghany 9f25167880 [squid:S1161] "@Override" annotation should be used on any method overriding (since Java 5) or implementing (since Java 6) another one 2016-06-07 14:04:11 +02:00
Diomidis Spinellis 23e7da7ca5 Merge pull request #15 from frankgrimes97/svg-uml-output
Output as SVG instead of PNG and minor cosmetic fixes.
2015-11-01 13:09:52 +02:00
Diomidis Spinellis 49a3f570bf Document package diagram generation 2015-10-05 15:14:30 +03:00
Diomidis Spinellis 93e69a4e24 Make umlgraph shell script work under Cygwin 2015-10-05 14:23:19 +03:00
Diomidis Spinellis ee82a7fd20 Update URLs for Javadoc and GraphViz 2014-10-29 09:23:04 +02:00
Diomidis Spinellis 17ab5f89f2 Update version 2014-10-29 00:19:04 +02:00
Diomidis Spinellis 9039a0011b [maven-release-plugin] prepare for next development iteration 2014-10-29 00:04:30 +02:00
Diomidis Spinellis 6700c90fe2 [maven-release-plugin] prepare release R5_7_2 2014-10-29 00:04:24 +02:00
Diomidis Spinellis 691cf7fe69 Add Version.java
Although it's auto-generated Maven wants it under SCM.
2014-10-29 00:03:19 +02:00
Diomidis Spinellis e2d2529ce6 [maven-release-plugin] prepare for next development iteration 2014-10-28 23:45:58 +02:00
Emanuel Pordes 44a146c03d Added width and height to svg object tag 2013-10-15 15:28:17 -04:00
Emanuel Pordes 41d93e14f6 Fix variable naming 2013-10-11 15:50:54 -04:00
Emanuel Pordes e58589e4c0 Output as SVG instead of PNG and minor cosmetic fixes. 2013-10-11 14:26:56 -04:00
130 changed files with 5028 additions and 4240 deletions

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="JDK_LIB/tools.jar"/>
<classpathentry kind="output" path="build"/>
</classpath>

4
.gitignore vendored
View File

@ -3,13 +3,15 @@
*.ipr
*.iws
*.swp
.idea
.settings
.project
.classpath
_vimrc
build
CHECKSUM.MD5
javadoc
lib
src/main/java/org/umlgraph/doclet/Version.java
TAGS
target
UMLGraph-R*

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>umlgraph_cvs</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

10
.travis.yml Normal file
View File

@ -0,0 +1,10 @@
language: java
addons:
apt:
packages:
- graphviz
install: ant
script: ant test

View File

@ -2,7 +2,7 @@ VERSION:=$(shell git describe --abbrev=6 HEAD | sed 's/R//;s/_/./;s/-/./;s/-.*$$
BALL_TAR_GZ=UMLGraph-$(VERSION).tar.gz
ZIPBALL=UMLGraph-$(VERSION).zip
DISTDIR=UMLGraph-$(VERSION)
WEBDIR=$(UH)/dds/pubs/web/home/sw/umlgraph-mirror
WEBDIR=$(UH)/dds/pubs/web/home/umlgraph
DOCLETSRCPATH=src/main/java/org/umlgraph/doclet
DOCLETSRC= \
$(DOCLETSRCPATH)/ClassGraph.java \
@ -65,7 +65,7 @@ test:
ant test
testupdate:
sh tools/testupdate.sh
bash tools/testupdate.sh
# Create only the static HTML pages
static-web:

69
README.md Normal file
View File

@ -0,0 +1,69 @@
# UMLGraph - Declarative Drawing of UML Diagrams
*UMLGraph* allows the declarative specification and drawing of UML diagrams.
You can browse the system's documentation
through [this link](http://www.spinellis.gr/umlgraph/doc/index.html),
or print it through [this link](http://www.spinellis.gr/umlgraph/doc/indexw.html).
In order to run *UMLGraph*, you need to have [GraphViz](https://www.graphviz.org/)
installed in your system path. On most Linux distributions, this can be easily
installed using the regular package manager.
To compile the Java doclet from the source code run *ant* on the
*build.xml* file.
If you change the source code, you can run regression tests by
executing *ant test*.
Visit the project's [home page](http://www.spinellis.gr/umlgraph) for more information.
## Compatibility
If you build against Java 8, please use latest version of 5.X of the Doclet.
Since Java 9 doclet APIs where completely rewritten, the Doclet in version 6 supports only supports Java 9 and above.
## Development versions
In order to use development versions, you can use [JitPack](https://jitpack.io/#dspinellis/UMLGraph/master-SNAPSHOT).
Note that as this is compiled on demand, you may sometimes see a "Read timed out" when the package is recompiled,
and it should be fine a few seconds later. And because the master branch can change any time, you may want to use
a versioned snapshot instead (see the Jitpack documentation for details).
**Gradle**:
```
repositories { maven { url 'https://jitpack.io' } }
configurations { umlgraph }
dependencies { umlgraph 'com.github.dspinellis:UMLGraph:master-SNAPSHOT' }
javadoc {
doclet = 'org.umlgraph.doclet.UmlGraphDoc'
docletpath = configurations.umlgraph.files.asType(List)
tags("hidden:X", "opt:X", "has:X", "navhas:X", "assoc:X", "navassoc:X",
"composed:X", "navcomposed:X", "stereotype:X", "depend:X")
}
```
**Maven**:
```
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
...
<dependency>
<groupId>com.github.dspinellis</groupId>
<artifactId>UMLGraph</artifactId>
<version>master-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
```
**Jar download**: <https://jitpack.io/com/github/dspinellis/UMLGraph/master-SNAPSHOT/UMLGraph-master-SNAPSHOT.jar>
## See also
* [D2: Declarative Diagraming](https://d2lang.com/) (Emphasis on aesthetics and extensionability)
* [Mermaid diagramming and charting tool](https://mermaid.js.org/) (JavaScript-based; easier syntax, good Markdown integration; interactive diagrams)
* [PlantUML](https://plantuml.com/) (Java-based; supports IDEs and more diagram types)
* [Comparison of textual diagraming systems](https://text-to-diagram.com/)

View File

@ -1,23 +0,0 @@
==UMLGraph - Declarative Drawing of UML Diagrams==
''UMLGraph'' allows the declarative specification and drawing of
UML diagrams.
You can browse the system's documentation
through [http://umlgraph.org/doc/index.html this link],
or print it through [http://umlgraph.org/doc/indexw.html this link].
To install the elements required to run ''UMLGraph'', simply copy
the contents of the ''lib'' directory to a location consistent with
your installation's conventions (for example to /usr/local/lib).
To compile the Java doclet from the source code run ''ant'' on the
''build.xml'' file.
If you change the source code, you can run regression tests by
executing ''ant test''.
Visit the project's [http://www.umlgraph.org home page] for more information.
----
Diomidis Spinellis - November 2005, August 2008, April 2012

View File

@ -1,21 +0,0 @@
UMLGraph - Declarative Drawing of UML Diagrams
UMLGraph allows the declarative specification and drawing of
UML class and sequence diagrams. You can browse the system's
documentation from the doc/index.html page, or print it from
doc/indexw.html.
To install the elements required to run UMLGraph, simply copy
the contents of the lib directory to a location consistent with
your installation's conventions (for example to /usr/local/lib).
To compile the Java doclet from the source code run ant on the
build.xml file.
If you change the source code, you can run regression tests by
executing "ant test".
Project home page: http://www.umlgraph.org
GitHub page: git@github.com:dspinellis/UMLGraph.git
Diomidis Spinellis - November 2005, August 2008, April 2012

2
TODO
View File

@ -1,5 +1,3 @@
When UMLGraph 2.29 comes out use <i></i> for italic fonts?
http://stackoverflow.com/questions/8609546/umlgraph-not-automatic-integrated-in-javadoc
Support for all UML diagrams: state, use-case, etc.

View File

@ -21,12 +21,12 @@
<macrodef name="gitversion" description="Get git version.">
<attribute name="outputproperty"/>
<sequential>
<echo message="git describe --abbrev=6 => '@{outputproperty}'"/>
<echo message="git rev-parse --short=6 => '@{outputproperty}'"/>
<exec executable="git"
failonerror="true"
outputproperty="@{outputproperty}">
<arg value="describe"/>
<arg value="--abbrev=6"/>
<arg value="rev-parse"/>
<arg value="--short=6"/>
<arg value="HEAD"/>
<redirector>
<outputfilterchain>
@ -64,6 +64,14 @@
<!-- import environment variables -->
<property environment="env"/>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${lib}"/>
<delete dir="testdata/dot-out"/>
<delete dir="${javadoc}"/>
<delete dir="${dist}/lib"/>
</target>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
@ -78,8 +86,8 @@
<target name="version">
<exec executable="git"
outputproperty="VERSION">
<arg value="describe"/>
<arg value="--abbrev=6"/>
<arg value="rev-parse"/>
<arg value="--short=6"/>
<arg value="HEAD"/>
</exec>
<echo>Version is ${VERSION}</echo>
@ -119,36 +127,44 @@ class Version { public static String VERSION = "${VERSION}";}
<target name="test" depends="compile,testcompile"
description="run the regression tests" >
<java classname="org.umlgraph.test.BasicTest" fork="true">
<classpath>
<pathelement location="${env.JAVA_HOME}/lib/tools.jar"/>
<pathelement location="${build}"/>
<pathelement location="${lib}/UmlGraph.jar"/>
</classpath>
</java>
<java classname="org.umlgraph.test.UmlDocTest" fork="true">
<classpath>
<pathelement location="${env.JAVA_HOME}/lib/tools.jar"/>
<pathelement location="${build}"/>
<pathelement location="${lib}/UmlGraph.jar"/>
</classpath>
</java>
<!-- postpone failures, so we get to see the pngs -->
<java classname="org.umlgraph.test.BasicTest" fork="true" resultproperty="BasicTest.exit">
<classpath>
<pathelement location="${env.JAVA_HOME}/lib/tools.jar"/>
<pathelement location="${build}"/>
<pathelement location="${lib}/UmlGraph.jar"/>
</classpath>
</java>
<java classname="org.umlgraph.test.UmlDocTest" fork="true" resultproperty="UmlDocTest.exit">
<classpath>
<pathelement location="${env.JAVA_HOME}/lib/tools.jar"/>
<pathelement location="${build}"/>
<pathelement location="${lib}/UmlGraph.jar"/>
</classpath>
</java>
<apply executable="dot" dest="${testout}" parallel="false">
<arg value="-Tpng"/>
<arg value="-o"/>
<targetfile/>
<srcfile/>
<fileset dir="${testout}" includes="*.dot"/>
<mapper type="glob" from="*.dot" to="*.png"/>
<fileset dir="${testout}" includes="*.dot"/>
<mapper type="glob" from="*.dot" to="*.png"/>
</apply>
<apply executable="dot" dest="${testref}" parallel="false">
<arg value="-Tpng"/>
<arg value="-o"/>
<targetfile/>
<srcfile/>
<fileset dir="${testref}" includes="*.dot"/>
<mapper type="glob" from="*.dot" to="*.png"/>
<fileset dir="${testref}" includes="*.dot"/>
<mapper type="glob" from="*.dot" to="*.png"/>
</apply>
<!-- postponed failure, so we get to see the pngs -->
<fail message="BasicTest failed">
<condition><not><equals arg1="0" arg2="${BasicTest.exit}"/></not></condition>
</fail>
<fail message="UmlDocTest failed">
<condition><not><equals arg1="0" arg2="${UmlDocTest.exit}"/></not></condition>
</fail>
</target>
<target name="javadocs" depends="compile">
@ -156,6 +172,7 @@ class Version { public static String VERSION = "${VERSION}";}
<doclet name="org.umlgraph.doclet.UmlGraphDoc" path="${lib}/UmlGraph.jar">
<param name="-inferrel"/>
<param name="-inferdep"/>
<param name="-autosize"/>
<param name="-collapsible"/>
<param name="-hide" value="java.*"/>
<param name="-collpackages" value="java.util.*"/>

View File

@ -4,7 +4,7 @@
ROOT=/cygdrive/c
PIC2PLOT=pic2plot
GS=gs
DESTDIR=/dds/pubs/web/home/sw/umlgraph-mirror
DESTDIR=/dds/pubs/web/home/umlgraph
NOTETOOLS=/dds/pubs/Courses/tools
GIF := $(shell sed -n 's/.*<img *src *= *"\([^.]*\.gif\)".*/\1/p' *.xml)
XML := $(wildcard *.xml)

View File

@ -46,6 +46,7 @@ UMLGraph would not be in its current state without their contributions.
<li>Soraya Santana de la Fe</li>
<li>Jonathan R. Santos</li>
<li>Jan Schl&#252;ter</li>
<li>Erich Schubert</li>
<li>Sebastian Setzer</li>
<li>J&#246;rn Guy S&#252;&#223;</li>
<li>Andreas Studer</li>

View File

@ -110,3 +110,14 @@
Note="Available online \url{http://java.dzone.com/articles/reverse-engineer-source-code-u}",
Author="Meera Subbarao"
}
@CONFERENCE{SG16,
author={Seifermann, S. and Groenda, H.},
title={Survey on textual notations for the Unified Modeling Language},
journal={MODELSWARD 2016 - Proceedings of the 4th International Conference on Model-Driven Engineering and Software Development},
year={2016},
pages={28--39},
note={cited By 0},
url={https://www.cooperate-project.de/images/publications/MODELSWARD2016.pdf},
document_type={Conference Paper},
}

View File

@ -72,6 +72,14 @@ Example:
java -jar /usr/jvm/java-1.5.0/lib/UmlGraph.jar -private Simple.java
</fmtcode>
<p />
To generate a diagram of all classes in the package specify as arguments
to the Java invocation the name of the package and the directory where
it resides.
The following example generates a diagram of all UMLGraph classes.
<fmtcode ext="sh">
java -classpath ... org.umlgraph.doclet.UmlGraph -sourcepath src/main/java org.umlgraph.doclet
</fmtcode>
<p />
Specifying some packages before the list of source files will designate
those packages as <em>local</em>.
When you specify a package list,

View File

@ -1,9 +1,10 @@
<?xml version="1.0" ?>
<notes>
A number of options contol the operation of UMLGraph
A number of options control the operation of UMLGraph
class diagram generator.
These can be specified on the command line, and most can also
be specified through javadoc tags within the diagram, affecting all or some elements.
be specified through javadoc <code>@opt</code> tags within the diagram, affecting all or some elements.
Most have a negated version by prefixing an exclamation mark.
<p/>
<h2>What Gets Drawn</h2> <!-- {{{1 -->
<dl>
@ -27,8 +28,12 @@ be specified through javadoc tags within the diagram, affecting all or some elem
in this case it will hide everything (useful in the context of views
to selectively unhide some portions of the graph, see the view chapter for
further details). </dd>
<dt>-include</dt><dd>Match classes to include with a non-anchored match. This is weaker than
the <code>-hide</code> option, but can be used to include classes from foreign packages
in the package view (which would by default filter to only include package members).</dd>
<dt>-operations</dt><dd>Show class operations (Java methods) </dd>
<dt>-qualify</dt><dd>Produce fully-qualified class names. </dd>
<dt>-qualifyGenerics</dt><dd>Use fully-qualified class names in Java generics.</dd>
<dt>-types</dt><dd>Add type information to attributes and operations </dd>
<dt>-view</dt><dd>Specify the fully qualified name of a class that contains
a view definition. Only the class diagram specified by this view will be generated.
@ -39,6 +44,7 @@ be specified through javadoc tags within the diagram, affecting all or some elem
<h2>Visual Appearance</h2> <!-- {{{1 -->
<dl>
<dt>-bgcolor</dt><dd>Specify the graph's background color. </dd>
<dt>-autosize</dt><dd>Fits generated graph to the width of the page/window. Defaults to true. </dd>
<dt>-collapsible</dt><dd>Enhance the javadoc HTML files containing UML diagrams with Javascript that provides a link for showing the (initially collapsed) diagrams. </dd>
<dt>-edgecolor</dt><dd>Specify the color for drawing edges. </dd>
<dt>-edgefontcolor</dt><dd>Specify the font color to use for edge labels. </dd>
@ -77,9 +83,9 @@ be specified through javadoc tags within the diagram, affecting all or some elem
<p />
All colors can be either a symbolic name (e.g. blue),
a tripple specifying hue-saturation-brightness as values 0-1
a triple specifying hue-saturation-brightness as values 0-1
(e.g. ".13 0.9 1"),
or a tripple specifying red-green-blue values as hexadecimal
or a triple specifying red-green-blue values as hexadecimal
digits prefixed by a # (e.g. "#ff8020").
The symbolic color names are derived from the X Windows System;
you can find a complete list in the
@ -182,10 +188,6 @@ When using <em>dot</em> to generate SVG diagrams you should specify
<code>UTF-8</code> as the output encoding, to have guillemots correctly
appearing in the resulting SVG.
</dd>
<dt>-verbose2</dt><dd>Will print on the standard output details regarding
the progress of graph generation.
(Note that -verbose is a javadoc option with a different meaning).
</dd>
</dl>
<!-- Footer {{{1 -->
</notes>

View File

@ -31,7 +31,7 @@ class SetTopController implements URLStreamHandler {
void connect() {}
}
/** @depend - <friend> - SetTopController */
/** @depend - &lt;friend&gt; - SetTopController */
class ChannelIterator {}
interface URLStreamHandler {

View File

@ -1,11 +1,12 @@
<?xml version="1.0" ?>
<notes>
The following was generated by annotating the source code of the
<a href="http://www.sqo-oss.org">SQO-OSS</a> project.
The following was generated by annotating the
<a href="https://github.com/istlab/Alitheia-Core/tree/master/alitheia/core/src/main/java/eu/sqooss/service/db">source code</a> of the
<a href="https://github.com/istlab/Alitheia-Core/">Alitheia Core</a> project.
Georgios Gousios, who created it, wrote:
<blockquote>
<p>
I've used UMLgraph to generate an E-R diagram out of the DAOs we use in SQO-OSS. I've just annotated a few classes with @assoc tags, removed the super class DAObject from all entities with sed, did some tweaking by hand in the .dot output, et voila, an E-R depicting almost 30 classes in less than 30 minutes!
I've used UMLgraph to generate an E-R diagram out of the DAOs we use in Alitheia Core. I've just annotated a few classes with @assoc tags, removed the super class DAObject from all entities with sed, did some tweaking by hand in the .dot output, et voila, an E-R depicting almost 30 classes in less than 30 minutes!
</p>
</blockquote>
<p />

View File

@ -20,8 +20,8 @@ class UMLOptions {}
class Person {
House[] houses;
List<Dog> dogs;
List&lt;Dog&gt; dogs;
public Room getFavouriteRoom(House house) {}
}
@ -29,7 +29,7 @@ class Person {
* @opt inferreltype composed
*/
class House {
Map<String, Room> nameRoomMap;
Map&lt;String, Room&gt; nameRoomMap;
}
class Room {}
@ -37,7 +37,6 @@ class Room {}
class Dog {
Person owner;
}
</fmtcode>
</td><td>
<img src="infer.png" alt="UML diagram with relationship inference" />

View File

@ -61,7 +61,7 @@ class DataOperation extends Element {}
<fmtcode ext="mak">
# Author: Vadim Nasardinov (vadimn@redhat.com)
# Since: 2004-05-26
# See: http://www.spinellis.gr/sw/umlgraph/doc/ceg-mv.html
# See: http://www.spinellis.gr/umlgraph/doc/ceg-mv.html
# Requires: graphviz
# Requires: javadoc
@ -93,18 +93,18 @@ clean:
build/%.dot : %.java
mkdir -p $(dir $@)
$(jd) $(jd_flags) $(detailed_flags) -output $@ $<
$(jd) $(jd_flags) $(detailed_flags) -output $@ $&lt;
build/%-small.dot : %.java
mkdir -p $(dir $@)
$(jd) $(jd_flags) -output $@ $<
$(jd) $(jd_flags) -output $@ $&lt;
%.png : %.dot
dot -Nheight=0.2 -Elabelfontcolor=DarkSlateBlue -Elabelfontsize=8 -Tpng -o $@ $<
dot -Nheight=0.2 -Elabelfontcolor=DarkSlateBlue -Elabelfontsize=8 -Tpng -o $@ $&lt;
build/%.png : %.fig
mkdir -p $(dir $@)
fig2dev -L png -S 4 $< $@
fig2dev -L png -S 4 $&lt; $@
dot: $(dot_files)
@ -112,7 +112,7 @@ png: $(png_files)
build/%.png : %.png
mkdir -p $(dir $@)
cp $< $@
cp $&lt; $@
# Example usage:
# make debug-java_files

View File

@ -30,7 +30,7 @@ async(); message(S,W,"liftReceiver"); sync();
active(S);
message(W,S,"setDialTone()");
async(); message(S,W,"*dialDigit(d)"); sync();
lconstraint(W,"{dialing.executionTime < 30s}");
lconstraint(W,"{dialing.executionTime &lt; 30s}");
active(W);
message(W,W,"routeCalls(s,n)");
inactive(W);

View File

@ -3,6 +3,21 @@
<dl>
<dt>Version 5.7 Under development </dt><dd>
<ul>
<li>The <code>@opt include</code> option can be used to include classes from
foreign packages in the package view (unless hidden with <code>@opt hide</code>).</li>
<li>You can now also use <code>@opt</code> in <code>package-info.java</code>.</li>
<li>Added <code>-qualifyGenerics</code> option to separately control the inclusion of
package names for the class (<code>-qualify</code>) and its generics. In particular
this works well with <code>-qualify -postfixpackage</code> (and <code>-!qualifyGenerics</code>).<br />
To get the old <code>-qualify</code> behavior, you need to add <code>-qualifyGenerics</code>,
the default is off, and it will not inherit from <code>-qualify</code>.</li>
<li>Better handling of complex names with generics and inner classes such as <code>pkg.Outer&lt;T&gt;.Inner</code>.</li>
<li>Use &lt;i&gt; tags for italic, because the old font naming approach does not work with SVG anymore.
Replace <code>-nodefontabstractname</code> and <code>-nodefontclassabstractname</code>
with a simple flag <code>-nodefontabstractitalic</code> instead.</li>
<li>Added <code>-hideprivateinner</code> to hide all private inner classes.</li>
</ul>
</dd>
<dt>Version 5.6 2012-05-31 </dt><dd>

View File

@ -10,7 +10,7 @@
<name>UMLGraph</name>
<version>${version}</version>
<description>Declarative Drawing of UML Diagrams</description>
<url>http://www.umlgraph.org</url>
<url>http://www.spinellis.gr/umlgraph</url>
<licenses>
<license>

95
pom.xml
View File

@ -6,9 +6,9 @@
<artifactId>umlgraph</artifactId>
<packaging>jar</packaging>
<name>UMLGraph</name>
<version>5.7.1</version>
<version>6.0.1-SNAPSHOT</version>
<description>Declarative Drawing of UML Diagrams</description>
<url>http://www.umlgraph.org</url>
<url>http://www.spinellis.gr/umlgraph</url>
<licenses>
<license>
@ -40,16 +40,15 @@
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
<version>9</version>
</parent>
<dependencies>
<dependency>
<groupId>sun.jdk</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -63,15 +62,16 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<version>3.10.1</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
<source>9</source>
<target>9</target>
</configuration>
</plugin> <plugin>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
@ -84,18 +84,18 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5</version>
<version>3.0.0-M7</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<useReleaseProfile>false</useReleaseProfile>
<releaseProfiles>release</releaseProfiles>
<goals>deploy</goals>
<autoVersionSubmodules>true</autoVersionSubmodules>
<useReleaseProfile>false</useReleaseProfile>
<releaseProfiles>release</releaseProfiles>
<goals>deploy</goals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
@ -108,35 +108,38 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<version>3.5.0</version>
<configuration>
<tags>
<tag>
<name>depend</name>
<placement>X</placement>
</tag>
<tag>
<name>hidden</name>
<placement>X</placement>
</tag>
<tag>
<name>opt</name>
<placement>X</placement>
</tag>
</tags>
<tags>
<tag>
<name>depend</name>
<placement>X</placement>
</tag>
<tag>
<name>hidden</name>
<placement>X</placement>
</tag>
<tag>
<name>opt</name>
<placement>X</placement>
</tag>
</tags>
<doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
<docletPath>${project.build.directory}${file.separator}${project.build.finalName}.jar</docletPath>
<additionalparam>-inferrel</additionalparam>
<additionalparam>-inferdep</additionalparam>
<additionalparam>-collapsible</additionalparam>
<additionalparam>-hide java.*</additionalparam>
<additionalparam>-collpackages</additionalparam>
<additionalparam>-qualify</additionalparam>
<additionalparam>-postfixpackage</additionalparam>
<additionalparam>-nodefontsize 9</additionalparam>
<additionalparam>-nodefontpackagesize 7</additionalparam>
<additionalparam>-link http://docs.oracle.com/javase/7/docs/jdk/api/javadoc/doclet/</additionalparam>
<additionalparam>-link http://download.oracle.com/javase/7/docs/api/</additionalparam>
<additionalOptions>
<option>-inferrel</option>
<option>-inferdep</option>
<option>-autosize</option>
<option>-collapsible</option>
<option>--hide="java.*"</option>
<option>--collpackages=</option>
<option>-qualify</option>
<option>-postfixpackage</option>
<option>-nodefontsize 9</option>
<option>-nodefontpackagesize 7</option>
<option>--link="https://docs.oracle.com/javase/9/docs/api/"</option>
</additionalOptions>
<detectJavaApiLink>false</detectJavaApiLink>
<useStandardDocletOptions>true</useStandardDocletOptions>
</configuration>
<executions>

View File

@ -0,0 +1,6 @@
module org.umlgraph.doclet {
exports org.umlgraph.doclet;
opens org.umlgraph.doclet;
requires transitive jdk.javadoc;
}

View File

@ -1 +0,0 @@
Version.java

File diff suppressed because it is too large Load Diff

View File

@ -20,55 +20,54 @@
package org.umlgraph.doclet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.Name;
/**
* Class's dot-compatible alias name (for fully qualified class names)
* and printed information
* Class's dot-compatible alias name (for fully qualified class names) and
* printed information
*
* @version $Revision$
* @author <a href="http://www.spinellis.gr">Diomidis Spinellis</a>
*/
class ClassInfo {
private static int classNumber;
/** Alias name for the class */
String name;
final String name;
/** True if the class class node has been printed */
boolean nodePrinted;
/** True if the class class node is hidden */
boolean hidden;
/**
* The list of classes that share a relation with this one. Contains
* all the classes linked with a bi-directional relation , and the ones
* referred by a directed relation
/**
* The list of classes that share a relation with this one. Contains all the
* classes linked with a bi-directional relation , and the ones referred by a
* directed relation
*/
Map<String, RelationPattern> relatedClasses = new HashMap<String, RelationPattern>();
Map<String, RelationPattern> relatedClasses = new HashMap<>();
ClassInfo(boolean p, boolean h) {
nodePrinted = p;
hidden = h;
name = "c" + (new Integer(classNumber)).toString();
classNumber++;
ClassInfo(boolean h) {
hidden = h;
name = "c" + classNumber;
classNumber++;
}
public void addRelation(String dest, RelationType rt, RelationDirection d) {
RelationPattern ri = relatedClasses.get(dest);
if(ri == null) {
ri = new RelationPattern(RelationDirection.NONE);
relatedClasses.put(dest, ri);
}
ri.addRelation(rt, d);
public void addRelation(Name dest, RelationType rt, RelationDirection d) {
RelationPattern ri = relatedClasses.get(dest.toString());
if (ri == null) {
ri = new RelationPattern(RelationDirection.NONE);
relatedClasses.put(dest.toString(), ri);
}
ri.addRelation(rt, d);
}
public RelationPattern getRelation(String dest) {
return relatedClasses.get(dest);
public RelationPattern getRelation(CharSequence dest) {
return relatedClasses.get(dest.toString());
}
/** Start numbering from zero. */
public static void reset() {
classNumber = 0;
classNumber = 0;
}
}

View File

@ -17,22 +17,22 @@
package org.umlgraph.doclet;
import com.sun.javadoc.ClassDoc;
import javax.lang.model.element.TypeElement;
/**
* A ClassMatcher is used to check if a class definition matches a
* specific condition. The nature of the condition is dependent on
* the kind of matcher
* A ClassMatcher is used to check if a class definition matches a specific
* condition. The nature of the condition is dependent on the kind of matcher
*
* @author wolf
*/
public interface ClassMatcher {
/**
* Returns the options for the specified class.
* Returns the options for the specified class.
*/
public boolean matches(ClassDoc cd);
public boolean matches(TypeElement cd);
/**
* Returns the options for the specified class.
* Returns the options for the specified class.
*/
public boolean matches(String name);
public boolean matches(CharSequence name);
}

View File

@ -26,8 +26,10 @@ import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.RootDoc;
import jdk.javadoc.doclet.DocletEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
/**
* Matches classes that are directly connected to one of the classes matched by
@ -38,6 +40,7 @@ import com.sun.javadoc.RootDoc;
* This class needs to perform quite a bit of computations in order to gather
* the network of class releationships, so you are allowed to reuse it should
* you
*
* @author wolf
*
* @depend - - - DevNullWriter
@ -45,34 +48,35 @@ import com.sun.javadoc.RootDoc;
public class ContextMatcher implements ClassMatcher {
ClassGraphHack cg;
Pattern pattern;
List<ClassDoc> matched;
Set<String> visited = new HashSet<String>();
List<TypeElement> matched;
Set<String> visited = new HashSet<>();
/** The options will be used to decide on inference */
Options opt;
RootDoc root;
DocletEnvironment root;
boolean keepParentHide;
/**
* Builds the context matcher
* @param root The root doc returned by JavaDoc
* @param pattern The pattern that will match the "center" of this
* context
* @param keepParentHide If true, parent option hide patterns will be
* preserved, so that classes hidden by the options won't
* be shown in the context
*
* @param root The root doc returned by JavaDoc
* @param pattern The pattern that will match the "center" of this
* context
* @param keepParentHide If true, parent option hide patterns will be preserved,
* so that classes hidden by the options won't be shown in
* the context
* @throws IOException
*/
public ContextMatcher(RootDoc root, Pattern pattern, Options options, boolean keepParentHide) throws IOException {
this.pattern = pattern;
this.root = root;
this.keepParentHide = keepParentHide;
opt = (Options) options.clone();
opt.setOption(new String[] { "-!hide" });
opt.setOption(new String[] { "-!attributes" });
opt.setOption(new String[] { "-!operations" });
this.cg = new ClassGraphHack(root, opt);
public ContextMatcher(DocletEnvironment root, Pattern pattern, Options options, boolean keepParentHide) throws IOException {
this.pattern = pattern;
this.root = root;
this.keepParentHide = keepParentHide;
opt = (Options) options.clone();
opt.setOption(new String[] { "!hide" });
opt.setOption(new String[] { "!attributes" });
opt.setOption(new String[] { "!operations" });
this.cg = new ClassGraphHack(root, opt);
setContextCenter(pattern);
setContextCenter(pattern);
}
/**
@ -80,117 +84,126 @@ public class ContextMatcher implements ClassMatcher {
* <p>
* This can be used to speed up subsequent matching with the same global
* options, since the class network informations will be reused.
*
* @param pattern
*/
public void setContextCenter(Pattern pattern) {
// build up the classgraph printing the relations for all of the
// classes that make up the "center" of this context
this.pattern = pattern;
matched = new ArrayList<ClassDoc>();
for (ClassDoc cd : root.classes()) {
if (pattern.matcher(cd.toString()).matches()) {
matched.add(cd);
addToGraph(cd);
}
}
// build up the classgraph printing the relations for all of the
// classes that make up the "center" of this context
this.pattern = pattern;
matched = new ArrayList<>();
for (Element cd : root.getIncludedElements()) {
if (cd instanceof TypeElement && pattern.matcher(cd.toString()).matches()) {
matched.add((TypeElement) cd);
addToGraph((TypeElement) cd);
}
}
}
/**
* Adds the specified class to the internal class graph along with its
* relations and depencies, eventually inferring them, according to the
* Options specified for this matcher
* Adds the specified class to the internal class graph along with its relations
* and dependencies, eventually inferring them, according to the Options
* specified for this matcher
*
* @param cd
*/
private void addToGraph(ClassDoc cd) {
// avoid adding twice the same class, but don't rely on cg.getClassInfo
// since there
// are other ways to add a classInfor than printing the class
if (visited.contains(cd.toString()))
return;
private void addToGraph(TypeElement cd) {
// avoid adding twice the same class, but don't rely on cg.getClassInfo
// since there are other ways to add a classInfor than printing the class
if (visited.contains(cd.toString())) {
return;
}
visited.add(cd.toString());
cg.printClass(cd, false);
cg.printRelations(cd);
if (opt.inferRelationships) {
cg.printInferredRelations(cd);
}
if (opt.inferDependencies) {
cg.printInferredDependencies(cd);
}
visited.add(cd.toString());
cg.printClass(cd, false);
cg.printRelations(cd);
if (opt.inferRelationships) {
cg.printInferredRelations(cd);
}
if (opt.inferDependencies) {
cg.printInferredDependencies(cd);
}
}
/**
* @see org.umlgraph.doclet.ClassMatcher#matches(com.sun.javadoc.ClassDoc)
* @see org.umlgraph.doclet.ClassMatcher#matches(TypeElement)
*/
public boolean matches(ClassDoc cd) {
if (keepParentHide && opt.matchesHideExpression(cd.toString()))
return false;
public boolean matches(TypeElement cd) {
if (keepParentHide && opt.matchesHideExpression(cd.getQualifiedName())) {
return false;
}
// if the class is matched, it's in by default.
if (matched.contains(cd))
return true;
// if the class is matched, it's in by default.
if (matched.contains(cd)) {
return true;
}
// otherwise, add the class to the graph and see if it's associated
// with any of the matched classes using the classgraph hack
addToGraph(cd);
return matches(cd.toString());
// otherwise, add the class to the graph and see if it's associated
// with any of the matched classes using the classgraph hack
addToGraph(cd);
return matches(cd.toString());
}
/**
* @see org.umlgraph.doclet.ClassMatcher#matches(java.lang.String)
* @see org.umlgraph.doclet.ClassMatcher#matches(CharSequence)
*/
public boolean matches(String name) {
if (pattern.matcher(name).matches())
return true;
public boolean matches(CharSequence name) {
if (pattern.matcher(name).matches()) {
return true;
}
for (ClassDoc mcd : matched) {
String mcName = mcd.toString();
ClassInfo ciMatched = cg.getClassInfo(mcName);
RelationPattern rp = ciMatched.getRelation(name);
if (ciMatched != null && rp != null && opt.contextRelationPattern.matchesOne(rp))
return true;
}
return false;
for (TypeElement mcd : matched) {
RelationPattern rp = cg.getClassInfo(mcd, true).getRelation(name);
if (rp != null && opt.contextRelationPattern.matchesOne(rp)) {
return true;
}
}
return false;
}
/**
* A quick hack to compute class dependencies reusing ClassGraph but
* without generating output. Will be removed once the ClassGraph class
* will be split into two classes for graph computation and output
* generation.
* A quick hack to compute class dependencies reusing ClassGraph but without
* generating output. Will be removed once the ClassGraph class will be split
* into two classes for graph computation and output generation.
*
* @author wolf
*
*/
private static class ClassGraphHack extends ClassGraph {
public ClassGraphHack(RootDoc root, OptionProvider optionProvider) throws IOException {
super(root, optionProvider, null);
prologue();
}
public ClassGraphHack(DocletEnvironment root, OptionProvider optionProvider) throws IOException {
super(root, optionProvider, null);
prologue();
}
public void prologue() throws IOException {
w = new PrintWriter(new DevNullWriter());
}
@Override
public void prologue() throws IOException {
w = new PrintWriter(new DevNullWriter());
}
}
/**
* Simple dev/null imitation
*
* @author wolf
*/
private static class DevNullWriter extends Writer {
public void write(char[] cbuf, int off, int len) throws IOException {
// nothing to do
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
// nothing to do
}
public void flush() throws IOException {
// nothing to do
}
@Override
public void flush() throws IOException {
// nothing to do
}
public void close() throws IOException {
// nothing to do
}
@Override
public void close() throws IOException {
// nothing to do
}
}

View File

@ -3,8 +3,14 @@ package org.umlgraph.doclet;
import java.io.IOException;
import java.util.regex.Pattern;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.RootDoc;
import jdk.javadoc.doclet.DocletEnvironment;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.TypeElement;
import org.umlgraph.doclet.util.ElementUtil;
import com.sun.source.util.DocTrees;
/**
* A view designed for UMLDoc, filters out everything that it's not directly
@ -14,105 +20,114 @@ import com.sun.javadoc.RootDoc;
* single {@linkplain ContextMatcher}, but provides some extra configuration
* such as context highlighting and output path configuration (and it is
* specified in code rather than in javadoc comments).
*
* @author wolf
*
*/
public class ContextView implements OptionProvider {
private ClassDoc cd;
private TypeElement cd;
private DocletEnvironment root;
private ContextMatcher matcher;
private Options globalOptions;
private Options myGlobalOptions;
private Options hideOptions;
private Options centerOptions;
private Options packageOptions;
private static final String[] HIDE_OPTIONS = new String[] { "-hide" };
private static final String[] HIDE_OPTIONS = new String[] { "hide" };
public ContextView(String outputFolder, ClassDoc cd, RootDoc root, Options parent)
throws IOException {
this.cd = cd;
String outputPath = cd.containingPackage().name().replace('.', '/') + "/" + cd.name()
+ ".dot";
public ContextView(String outputFolder, TypeElement cd, DocletEnvironment root, Options parent) throws IOException {
this.cd = cd;
this.root = root;
ModuleElement md = ElementUtil.getModuleOf(root, cd);
String pathPrefix = Runtime.version().major() > 10 && md != null ? md.getQualifiedName().toString() + "/" : "";
String outputPath = pathPrefix + ElementUtil.getPackageOf(root, cd).getQualifiedName().toString().replace('.', '/') + "/" + cd.getSimpleName() + ".dot";
// setup options statically, so that we won't need to change them so
// often
this.globalOptions = parent.getGlobalOptions();
this.packageOptions = parent.getGlobalOptions();
this.packageOptions.showQualified = false;
// setup options statically, so that we won't need to change them so
// often
this.globalOptions = parent.getGlobalOptions();
this.myGlobalOptions = parent.getGlobalOptions();
this.myGlobalOptions.setOption(new String[] { "-output", outputPath });
this.myGlobalOptions.setOption(HIDE_OPTIONS);
this.packageOptions = parent.getGlobalOptions();
this.packageOptions.showQualified = false;
this.hideOptions = parent.getGlobalOptions();
this.hideOptions.setOption(HIDE_OPTIONS);
this.myGlobalOptions = parent.getGlobalOptions();
this.myGlobalOptions.setOption(new String[] { "output", outputPath });
this.myGlobalOptions.setOption(HIDE_OPTIONS);
this.centerOptions = parent.getGlobalOptions();
this.centerOptions.nodeFillColor = "lemonChiffon";
this.centerOptions.showQualified = false;
this.hideOptions = parent.getGlobalOptions();
this.hideOptions.setOption(HIDE_OPTIONS);
this.matcher = new ContextMatcher(root, Pattern.compile(cd.qualifiedName()),
myGlobalOptions, true);
this.centerOptions = parent.getGlobalOptions();
this.centerOptions.nodeFillColor = "lemonChiffon";
this.centerOptions.showQualified = false;
this.matcher = new ContextMatcher(root, Pattern.compile(Pattern.quote(cd.toString())), myGlobalOptions, true);
}
public void setContextCenter(ClassDoc contextCenter) {
this.cd = contextCenter;
String outputPath = cd.containingPackage().name().replace('.', '/') + "/" + cd.name()
+ ".dot";
this.myGlobalOptions.setOption(new String[] { "-output", outputPath });
matcher.setContextCenter(Pattern.compile(cd.toString()));
public void setContextCenter(TypeElement contextCenter) {
this.cd = contextCenter;
ModuleElement md = ElementUtil.getModuleOf(root, contextCenter);
String pathPrefix = Runtime.version().major() > 10 && md != null ? md.getQualifiedName().toString() + "/" : "";
String outputPath = pathPrefix + ElementUtil.getPackageOf(root, cd).getQualifiedName().toString().replace('.', '/') + "/" + cd.getSimpleName() + ".dot";
this.myGlobalOptions.setOption(new String[] { "output", outputPath });
matcher.setContextCenter(Pattern.compile(Pattern.quote(cd.toString())));
}
public String getDisplayName() {
return "Context view for class " + cd;
return "Context view for class " + cd;
}
public Options getGlobalOptions() {
return myGlobalOptions;
return myGlobalOptions;
}
public Options getOptionsFor(ClassDoc cd) {
Options opt;
if (globalOptions.matchesHideExpression(cd.toString()) || !matcher.matches(cd)) {
opt = hideOptions;
} else if (cd.equals(this.cd)) {
opt = centerOptions;
} else if(cd.containingPackage().equals(this.cd.containingPackage())){
opt = packageOptions;
} else {
opt = globalOptions;
}
Options optionClone = (Options) opt.clone();
overrideForClass(optionClone, cd);
return optionClone;
public Options getOptionsFor(DocTrees dt, TypeElement cd) {
Options opt;
if (globalOptions.matchesHideExpression(cd.getQualifiedName())
|| !(matcher.matches(cd) || globalOptions.matchesIncludeExpression(cd.getQualifiedName()))) {
opt = hideOptions;
} else if (cd.equals(this.cd)) {
opt = centerOptions;
} else if (root.getElementUtils().getPackageOf(cd).equals(root.getElementUtils().getPackageOf(this.cd))) {
opt = packageOptions;
} else {
opt = globalOptions;
}
Options optionClone = (Options) opt.clone();
overrideForClass(optionClone, cd);
return optionClone;
}
public Options getOptionsFor(String name) {
Options opt;
if (!matcher.matches(name))
opt = hideOptions;
else if (name.equals(cd.name()))
opt = centerOptions;
else
opt = globalOptions;
Options optionClone = (Options) opt.clone();
overrideForClass(optionClone, name);
return optionClone;
public Options getOptionsFor(CharSequence name) {
Options opt;
if (!matcher.matches(name)) {
opt = hideOptions;
} else if (name.equals(cd.getSimpleName())) {
opt = centerOptions;
} else {
opt = globalOptions;
}
Options optionClone = (Options) opt.clone();
overrideForClass(optionClone, name);
return optionClone;
}
public void overrideForClass(Options opt, ClassDoc cd) {
opt.setOptions(cd);
if (opt.matchesHideExpression(cd.toString()) || !matcher.matches(cd))
opt.setOption(HIDE_OPTIONS);
if (cd.equals(this.cd))
opt.nodeFillColor = "lemonChiffon";
public void overrideForClass(Options opt, TypeElement cd) {
opt.setOptions(root.getDocTrees(), cd);
if (opt.matchesHideExpression(cd.getQualifiedName())
|| !(matcher.matches(cd) || opt.matchesIncludeExpression(cd.getQualifiedName()))) {
opt.setOption(HIDE_OPTIONS);
}
if (cd.equals(this.cd)) {
opt.nodeFillColor = "lemonChiffon";
}
}
public void overrideForClass(Options opt, String className) {
if (!matcher.matches(className))
opt.setOption(HIDE_OPTIONS);
public void overrideForClass(Options opt, CharSequence className) {
if (!(matcher.matches(className) || opt.matchesIncludeExpression(className))) {
opt.setOption(HIDE_OPTIONS);
}
}
}

View File

@ -0,0 +1,101 @@
package org.umlgraph.doclet;
/**
* Class to represent a font for graphviz.
* <p>
* This is a fairly complicated model, because it is rather an API into graphviz
* formatting strings rather than a standalone thing. <p> Some fonts (edge, node,
* abstract) are set on the top level elements, whereas others (class name, tag,
* package) are inserted as {@code <font>} tags, and these can be omitted if not
* set. Inheritance of properties then happens in graphviz.
*
* @author Erich Schubert
*/
public enum Font {
/** Edge label font */
EDGE, //
/** Node basic */
NODE, //
/** Normal operation font */
NORMAL, //
/** Abstract operation font */
ABSTRACT, //
/** Class name. Inherits from null. */
CLASS, //
/** Class name of abstract classes (usually italic) */
CLASS_ABSTRACT, //
/** Package names Inherits from null. */
PACKAGE, //
/** Tags Inherits from null. */
TAG;
public static final String DEFAULT_FONT;
// Static initialization of further values.
static {
// use an appropriate font depending on the current operating system
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
DEFAULT_FONT = "Arial";
} else {
DEFAULT_FONT = "Helvetica"; // TODO: can we use just "sans"?
}
}
/**
* Wraps the text with the appropriate font according to the specified font type
*
* @param opt Options
* @param text Text to wrap
* @return Wrapped text
*/
public String wrap(Options opt, String text) {
if (text.isEmpty() || this == NORMAL)
return text;
String face = null;
double size = -1;
boolean italic = false;
switch (this) {
case EDGE:
case NODE:
// Not used with the wrap function.
throw new UnsupportedOperationException();
case ABSTRACT:
italic = opt.nodeFontAbstractItalic;
case NORMAL:
break;
case CLASS_ABSTRACT:
italic = opt.nodeFontAbstractItalic;
case CLASS:
face = opt.nodeFontClassName;
size = opt.nodeFontClassSize;
break;
case PACKAGE:
face = opt.nodeFontPackageName;
size = opt.nodeFontPackageSize;
break;
case TAG:
face = opt.nodeFontTagName;
size = opt.nodeFontTagSize;
break;
}
if (face == null && size < 0 && !italic)
return text;
StringBuilder buf = new StringBuilder(text.length() + 100);
if (face != null || size > 0) {
buf.append("<font");
if (face != null)
buf.append(" face=\"").append(face).append('"');
if (size > 0)
buf.append(" point-size=\"").append(size).append('"');
buf.append('>');
}
if (italic)
buf.append("<i>");
buf.append(text);
if (italic)
buf.append("</i>");
if (face != null || size > 0)
buf.append("</font>");
return buf.toString();
}
}

View File

@ -2,47 +2,51 @@ package org.umlgraph.doclet;
import java.util.regex.Pattern;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.RootDoc;
import jdk.javadoc.doclet.DocletEnvironment;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import org.umlgraph.doclet.util.ElementUtil;
/**
* Matches every class that implements (directly or indirectly) an
* interfaces matched by regular expression provided.
* Matches every class that implements (directly or indirectly) an interfaces
* matched by regular expression provided.
*/
public class InterfaceMatcher implements ClassMatcher {
protected RootDoc root;
protected DocletEnvironment root;
protected Pattern pattern;
public InterfaceMatcher(RootDoc root, Pattern pattern) {
this.root = root;
this.pattern = pattern;
public InterfaceMatcher(DocletEnvironment root, Pattern pattern) {
this.root = root;
this.pattern = pattern;
}
public boolean matches(ClassDoc cd) {
// if it's the interface we're looking for, match
if(cd.isInterface() && pattern.matcher(cd.toString()).matches())
return true;
// for each interface, recurse, since classes and interfaces
// are treated the same in the doclet API
for (ClassDoc iface : cd.interfaces()) {
if(matches(iface))
return true;
}
// recurse on supeclass, if available
if(cd.superclass() != null)
return matches(cd.superclass());
return false;
public boolean matches(TypeElement cd) {
// if it's the interface we're looking for, match
if (cd.getKind() == ElementKind.INTERFACE && pattern.matcher(cd.toString()).matches()) {
return true;
}
// for each interface, recurse, since classes and interfaces
// are treated the same in the doclet API
for (TypeMirror type : cd.getInterfaces()) {
TypeElement iType = ElementUtil.getTypeElement(type);
if (iType != null && matches(iType)) {
return true;
}
}
// recurse on superclass, if available
TypeElement scd = ElementUtil.getTypeElement(cd.getSuperclass());
return scd == null ? false : matches(scd);
}
public boolean matches(String name) {
ClassDoc cd = root.classNamed(name);
if(cd == null)
return false;
return matches(cd);
public boolean matches(CharSequence name) {
TypeElement cd = root.getElementUtils().getTypeElement(name);
return cd == null ? false : matches(cd);
}
}

View File

@ -0,0 +1,53 @@
package org.umlgraph.doclet;
import java.util.List;
import jdk.javadoc.doclet.Doclet;
/**
* A base class for declaring options. Subtypes for specific options should
* implement the {@link #process(String,List) process} method to handle
* instances of the option found on the command line.
*/
public abstract class Option implements Doclet.Option {
private final String name;
private final int argumentCount;
private final String description;
private final String parameters;
public Option(String name, boolean hasArg, String description, String parameters) {
this(name, hasArg ? 1 : 0, description, parameters);
}
public Option(String name, int argumentCount, String description, String parameters) {
this.name = name;
this.argumentCount = argumentCount;
this.description = description;
this.parameters = parameters;
}
@Override
public int getArgumentCount() {
return argumentCount;
}
@Override
public String getDescription() {
return description;
}
@Override
public Kind getKind() {
return Kind.STANDARD;
}
@Override
public List<String> getNames() {
return List.of(name);
}
@Override
public String getParameters() {
return argumentCount == 0 ? "" : parameters;
}
}

View File

@ -17,22 +17,23 @@
package org.umlgraph.doclet;
import com.sun.javadoc.ClassDoc;
import javax.lang.model.element.TypeElement;
import com.sun.source.util.DocTrees;
/**
* A factory class that builds Options object for general use or for a
* specific class
* A factory class that builds Options object for general use or for a specific class
*/
public interface OptionProvider {
/**
* Returns the options for the specified class.
*/
public Options getOptionsFor(ClassDoc cd);
public Options getOptionsFor(DocTrees dt, TypeElement cd);
/**
* Returns the options for the specified class.
*/
public Options getOptionsFor(String name);
public Options getOptionsFor(CharSequence name);
/**
* Returns the global options (the class independent definition)
@ -42,16 +43,17 @@ public interface OptionProvider {
/**
* Gets a base Options and applies the overrides for the specified class
*/
public void overrideForClass(Options opt, ClassDoc cd);
public void overrideForClass(Options opt, TypeElement cd);
/**
* Gets a base Options and applies the overrides for the specified class
*/
public void overrideForClass(Options opt, String className);
public void overrideForClass(Options opt, CharSequence className);
/**
* Returns user displayable name for this option provider.
* <p>Will be used to provide progress feedback on the console
* <p>
* Will be used to provide progress feedback on the console
*/
public String getDisplayName();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,33 @@
package org.umlgraph.doclet;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.PackageDoc;
import jdk.javadoc.doclet.DocletEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import org.umlgraph.doclet.util.ElementUtil;
public class PackageMatcher implements ClassMatcher {
protected PackageDoc packageDoc;
protected DocletEnvironment root;
protected PackageElement packageDoc;
public PackageMatcher(PackageDoc packageDoc) {
super();
this.packageDoc = packageDoc;
public PackageMatcher(DocletEnvironment root, PackageElement packageDoc) {
this.root = root;
this.packageDoc = packageDoc;
}
public boolean matches(ClassDoc cd) {
return cd.containingPackage().equals(packageDoc);
public boolean matches(TypeElement cd) {
return packageDoc.equals(ElementUtil.getPackageOf(root, cd));
}
public boolean matches(String name) {
for (ClassDoc cd : packageDoc.allClasses()) {
if (cd.qualifiedName().equals(name))
return true;
}
return false;
public boolean matches(CharSequence name) {
for (Element cd : packageDoc.getEnclosedElements()) {
if (cd instanceof TypeElement && ((TypeElement) cd).getQualifiedName().equals(name)) {
return true;
}
}
return false;
}
}

View File

@ -1,8 +1,14 @@
package org.umlgraph.doclet;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.RootDoc;
import jdk.javadoc.doclet.DocletEnvironment;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import org.umlgraph.doclet.util.ElementUtil;
import com.sun.source.util.DocTrees;
/**
* A view designed for UMLDoc, filters out everything that it's not contained in
@ -12,59 +18,78 @@ import com.sun.javadoc.RootDoc;
* single {@linkplain ClassMatcher}, and provides some extra configuration such
* as output path configuration (and it is specified in code rather than in
* javadoc comments).
*
* @author wolf
*
*/
public class PackageView implements OptionProvider {
private PackageDoc pd;
private static final String[] HIDE = new String[] { "hide" };
private PackageElement pd;
private OptionProvider parent;
private ClassMatcher matcher;
private String outputPath;
private Options opt;
private DocTrees docTrees;
public PackageView(String outputFolder, PackageDoc pd, RootDoc root, OptionProvider parent) {
this.parent = parent;
this.pd = pd;
this.matcher = new PackageMatcher(pd);
this.outputPath = pd.name().replace('.', '/') + "/" + pd.name() + ".dot";
public PackageView(String outputFolder, PackageElement pd, DocletEnvironment root, OptionProvider parent) {
this.parent = parent;
this.pd = pd;
this.docTrees = root.getDocTrees();
this.matcher = new PackageMatcher(root, pd);
this.opt = parent.getGlobalOptions();
this.opt.setOptions(docTrees, pd);
ModuleElement md = ElementUtil.getModuleOf(root, pd);
String pathPrefix = Runtime.version().major() > 10 && md != null ? md.getQualifiedName().toString() + "/" : "";
this.outputPath = pathPrefix + pd.getQualifiedName().toString().replace('.', '/') + "/" + pd.getSimpleName().toString() + ".dot";
}
public String getDisplayName() {
return "Package view for package " + pd;
return "Package view for package " + pd;
}
public Options getGlobalOptions() {
Options go = parent.getGlobalOptions();
Options go = parent.getGlobalOptions();
go.setOption(new String[] { "-output", outputPath });
go.setOption(new String[] { "-hide" });
go.setOption(new String[] { "output", outputPath });
go.setOption(HIDE);
return go;
return go;
}
public Options getOptionsFor(ClassDoc cd) {
Options go = parent.getGlobalOptions();
overrideForClass(go, cd);
return go;
public Options getOptionsFor(DocTrees dt, TypeElement cd) {
Options go = parent.getGlobalOptions();
overrideForClass(go, cd);
return go;
}
public Options getOptionsFor(String name) {
Options go = parent.getGlobalOptions();
overrideForClass(go, name);
return go;
public Options getOptionsFor(CharSequence name) {
Options go = parent.getGlobalOptions();
overrideForClass(go, name);
return go;
}
public void overrideForClass(Options opt, ClassDoc cd) {
opt.setOptions(cd);
opt.showQualified = false;
if (!matcher.matches(cd) || parent.getGlobalOptions().matchesHideExpression(cd.name()))
opt.setOption(new String[] { "-hide" });
public void overrideForClass(Options opt, TypeElement cd) {
opt.setOptions(docTrees, cd);
boolean inPackage = matcher.matches(cd);
if (inPackage) {
opt.showQualified = false;
}
boolean included = inPackage || this.opt.matchesIncludeExpression(cd.getQualifiedName());
if (!included || this.opt.matchesHideExpression(cd.getQualifiedName())) {
opt.setOption(HIDE);
}
}
public void overrideForClass(Options opt, String className) {
opt.showQualified = false;
if (!matcher.matches(className))
opt.setOption(new String[] { "-hide" });
public void overrideForClass(Options opt, CharSequence className) {
opt.showQualified = false;
boolean inPackage = matcher.matches(className);
if (inPackage)
opt.showQualified = false;
boolean included = inPackage || this.opt.matchesIncludeExpression(className);
if (!included || this.opt.matchesHideExpression(className)) {
opt.setOption(HIDE);
}
}
}

View File

@ -16,30 +16,29 @@
*/
package org.umlgraph.doclet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.sun.javadoc.ClassDoc;
import javax.lang.model.element.TypeElement;
/**
* Matches classes performing a regular expression match on the qualified class
* name
*
* @author wolf
*/
public class PatternMatcher implements ClassMatcher {
Pattern pattern;
public PatternMatcher(Pattern pattern) {
this.pattern = pattern;
this.pattern = pattern;
}
public boolean matches(ClassDoc cd) {
return matches(cd.toString());
public boolean matches(TypeElement cd) {
return matches(cd.getQualifiedName());
}
public boolean matches(String name) {
Matcher matcher = pattern.matcher(name);
return matcher.matches();
public boolean matches(CharSequence name) {
return pattern.matcher(name).matches();
}
}

View File

@ -9,43 +9,35 @@ public enum RelationDirection {
/**
* Adds the current direction
*
* @param d
* @return
*/
public RelationDirection sum(RelationDirection d) {
if (this == NONE)
return d;
if ((this == IN && d == OUT) || (this == OUT && d == IN) || this == BOTH || d == BOTH)
return BOTH;
return this;
// Handle same and nones first:
return (this == d || d == NONE) ? this : //
this == NONE ? d : BOTH; // They are different and not none.
}
/**
* Returns true if this direction "contains" the specified one, that is,
* either it's equal to it, or this direction is {@link #BOTH}
* Returns true if this direction "contains" the specified one, that is, either
* it's equal to it, or this direction is {@link #BOTH}
*
* @param d
* @return
*/
public boolean contains(RelationDirection d) {
if (this == BOTH)
return true;
else
return d == this;
return this == BOTH ? true : (d == this);
}
/**
* Inverts the direction of the relation. Turns IN into OUT and vice-versa, NONE and BOTH
* are not changed
* Inverts the direction of the relation. Turns IN into OUT and vice-versa, NONE
* and BOTH are not changed
*
* @return
*/
public RelationDirection inverse() {
if (this == IN)
return OUT;
else if (this == OUT)
return IN;
else
return this;
return this == IN ? OUT : this == OUT ? IN : this;
}
};

View File

@ -2,6 +2,7 @@ package org.umlgraph.doclet;
/**
* A map from relation types to directions
*
* @author wolf
*
*/
@ -13,38 +14,41 @@ public class RelationPattern {
/**
* Creates a new pattern using the same direction for every relation kind
*
* @param defaultDirection The direction used to initialize this pattern
*/
public RelationPattern(RelationDirection defaultDirection) {
directions = new RelationDirection[RelationType.values().length];
for (int i = 0; i < directions.length; i++) {
directions[i] = defaultDirection;
}
directions = new RelationDirection[RelationType.values().length];
for (int i = 0; i < directions.length; i++) {
directions[i] = defaultDirection;
}
}
/**
* Adds, eventually merging, a direction for the specified relation type
*
* @param relationType
* @param direction
*/
public void addRelation(RelationType relationType, RelationDirection direction) {
int idx = relationType.ordinal();
directions[idx] = directions[idx].sum(direction);
int idx = relationType.ordinal();
directions[idx] = directions[idx].sum(direction);
}
/**
* Returns true if this patterns matches at least the direction of one
* of the relations in the other relation patterns. Matching is defined
* by {@linkplain RelationDirection#contains(RelationDirection)}
* Returns true if this patterns matches at least the direction of one of the
* relations in the other relation patterns. Matching is defined by
* {@linkplain RelationDirection#contains(RelationDirection)}
*
* @param relationPattern
* @return
*/
public boolean matchesOne(RelationPattern relationPattern) {
for (int i = 0; i < directions.length; i++) {
if (directions[i].contains(relationPattern.directions[i]))
return true;
}
return false;
for (int i = 0; i < directions.length; i++) {
if (directions[i].contains(relationPattern.directions[i]))
return true;
}
return false;
}
}

View File

@ -1,10 +1,34 @@
package org.umlgraph.doclet;
/**
* The type of relation that links two entities
* @author wolf
* The type of relation that links two entities, and the graphviz format
*
* @author Erich Schubert
*/
public enum RelationType {
ASSOC, NAVASSOC, HAS, NAVHAS, COMPOSED, NAVCOMPOSED, DEPEND, EXTENDS, IMPLEMENTS;
DEPEND("arrowhead=open,style=dashed,weight=0", false), // Weakest
NAVASSOC("arrowhead=open,weight=1", false), //
ASSOC("arrowhead=none,weight=2", false), //
NAVHAS("arrowhead=open,arrowtail=ediamond,dir=both,weight=3", false), //
HAS("arrowhead=none,arrowtail=ediamond,dir=back,weight=4", false), //
NAVCOMPOSED("arrowhead=open,arrowtail=diamond,dir=both,weight=5", false), //
COMPOSED("arrowhead=none,arrowtail=diamond,dir=back,weight=6", false), //
IMPLEMENTS("arrowtail=empty,style=dashed,dir=back,weight=9", true), //
EXTENDS("arrowtail=empty,dir=back,weight=10", true);
/** Lower case version of the label */
public final String lower;
/** Graphviz style */
public final String style;
/** Backwards edges with respect to node ranking */
public final boolean backorder;
/** Enum constructors must be private */
private RelationType(String style, boolean backorder) {
this.lower = toString().toLowerCase();
this.style = style;
this.backorder = backorder;
}
}

View File

@ -18,80 +18,66 @@
package org.umlgraph.doclet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.Doc;
import com.sun.javadoc.LanguageVersion;
import com.sun.javadoc.RootDoc;
import java.util.HashMap;
import java.util.Locale;
/**
* Properties of node shapes
*
* @version $Revision$
* @author <a href="http://www.spinellis.gr">Diomidis Spinellis</a>
* @author Erich Schubert
*/
public class Shape {
public enum Shape {
CLASS(""), //
NOTE(", shape=note"), //
NODE(", shape=box3d"), //
COMPONENT(", shape=component"), //
PACKAGE(", shape=tab"), //
COLLABORATION(", shape=ellipse, style=dashed"), //
USECASE(", shape=ellipse"), //
ACTIVECLASS("");
/** Shape's UMLGraph name */
private String name;
/** Graphviz style */
public final String style;
/** Construct a default (class) Shape */
public Shape() {
name = "class";
}
/** Map for valid shape names */
private static final HashMap<String, Shape> index = new HashMap<String, Shape>(16);
/** Construct a Shape through the specified UMLGraph name */
public Shape(String n) {
name = n;
if (graphvizAttribute() == null) {
System.err.println("Ignoring invalid shape " + n);
name = "class";
}
/** Initialize the lookup index */
static {
for (Shape s : Shape.values()) {
index.put(s.name(), s);
index.put(s.name().toLowerCase(Locale.ROOT), s);
}
}
/**
* Return the GraphViz shape name corresponding to the shape
* Get the shape from a string. This allows both the uppercase and the lowercase
* name. Prefer this to {{@link #valueOf(String)} which only accepts uppercase.
*
* @param s String
* @return Shape
*/
public String graphvizAttribute() {
if (name.equals("class"))
return ""; // Default; plaintext
else if (name.equals("note"))
return ", shape=note";
else if (name.equals("node"))
return ", shape=box3d";
else if (name.equals("component"))
return ", shape=component";
else if (name.equals("package"))
return ", shape=tab";
else if (name.equals("collaboration"))
return ", shape=ellipse, style=dashed";
else if (name.equals("usecase"))
return ", shape=ellipse";
else if (name.equals("activeclass"))
return ""; // Default; plaintext
else
return null;
public static Shape of(String s) {
Shape shp = index.get(s);
if (shp != null)
return shp;
System.err.println("Ignoring invalid shape: " + s);
return CLASS;
}
/** Return the shape's GraphViz landing port */
String landingPort() {
if (name.equals("class") || name.equals("activeclass"))
return ":p";
else
return "";
/** Enum constructor, must be private! */
private Shape(String style) {
this.style = style;
}
/** Return the table border required for the shape */
String extraColumn(int nRows) {
return name.equals("activeclass") ? ("<td rowspan=\"" + nRows + "\"></td>") : "";
public String extraColumn() {
return this == Shape.ACTIVECLASS ? ("<td rowspan=\"10\"></td>") : "";
}
/** Return the cell border required for the shape */
String cellBorder() {
return (name.equals("class") || name.equals("activeclass")) ? "1" : "0";
public String cellBorder() {
return this == CLASS || this == ACTIVECLASS ? "1" : "0";
}
}

View File

@ -19,47 +19,221 @@
package org.umlgraph.doclet;
import javax.lang.model.element.Name;
import javax.lang.model.util.Elements;
import java.util.*;
import java.util.regex.Pattern;
/**
* String utility functions
*
* @version $Revision$
* @author <a href="http://www.spinellis.gr">Diomidis Spinellis</a>
*/
class StringUtil {
/** Tokenize string s into an array */
public static String[] tokenize(String s) {
ArrayList<String> r = new ArrayList<String>();
String remain = s;
int n = 0, pos;
ArrayList<String> r = new ArrayList<String>();
String remain = s;
int n = 0, pos;
remain = remain.trim();
while (remain.length() > 0) {
if (remain.startsWith("\"")) {
// Field in quotes
pos = remain.indexOf('"', 1);
if (pos == -1)
break;
r.add(remain.substring(1, pos));
if (pos + 1 < remain.length())
pos++;
} else {
// Space-separated field
pos = remain.indexOf(' ', 0);
if (pos == -1) {
r.add(remain);
remain = "";
} else
r.add(remain.substring(0, pos));
}
remain = remain.substring(pos + 1);
remain = remain.trim();
// - is used as a placeholder for empy fields
if (r.get(n).equals("-"))
r.set(n, "");
n++;
}
return r.toArray(new String[0]);
remain = remain.trim();
while (remain.length() > 0) {
if (remain.startsWith("\"")) {
// Field in quotes
pos = remain.indexOf('"', 1);
if (pos == -1)
break;
r.add(remain.substring(1, pos));
if (pos + 1 < remain.length())
pos++;
} else {
// Space-separated field
pos = remain.indexOf(' ', 0);
if (pos == -1) {
r.add(remain);
remain = "";
} else
r.add(remain.substring(0, pos));
}
remain = remain.substring(pos + 1);
remain = remain.trim();
// - is used as a placeholder for empy fields
if (r.get(n).equals("-"))
r.set(n, "");
n++;
}
return r.toArray(new String[0]);
}
private final static Pattern ESCAPE_BASIC_XML = Pattern.compile("[&<>]");
/**
* Escape &lt;, &gt;, and &amp; characters in the string with the corresponding
* HTML entity code.
*/
public static String escape(String s) {
if (ESCAPE_BASIC_XML.matcher(s).find()) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length();) {
switch (sb.charAt(i)) {
case '&':
sb.replace(i, i + 1, "&amp;");
i += "&amp;".length();
break;
case '<':
sb.replace(i, i + 1, "&lt;");
i += "&lt;".length();
break;
case '>':
sb.replace(i, i + 1, "&gt;");
i += "&gt;".length();
break;
default:
i++;
}
}
return sb.toString();
} else
return s;
}
/**
* Convert embedded newlines into HTML line breaks
*/
public static String htmlNewline(String s) {
if (s.indexOf('\n') == -1)
return s;
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length();) {
if (sb.charAt(i) == '\n') {
sb.replace(i, i + 1, "<br/>");
i += "<br/>".length();
} else
i++;
}
return sb.toString();
}
/**
* Convert &lt; and &gt; characters in the string to the respective guillemot
* characters.
*/
public static String guillemize(Options opt, String s) {
StringBuilder r = new StringBuilder(s);
for (int i = 0; i < r.length();)
switch (r.charAt(i)) {
case '<':
r.replace(i, i + 1, opt.guilOpen);
i += opt.guilOpen.length();
break;
case '>':
r.replace(i, i + 1, opt.guilClose);
i += opt.guilClose.length();
break;
default:
i++;
break;
}
return r.toString();
}
/**
* Wraps a string in Guillemot (or an ASCII substitute) characters.
*
* @param str the <code>String</code> to be wrapped.
* @return the wrapped <code>String</code>.
*/
public static String guilWrap(Options opt, String str) {
return opt.guilOpen + str + opt.guilClose;
}
/** Removes the template specs from a class name. */
public static Name removeTemplate(Elements elements, Name name) {
int openIdx = name.toString().indexOf('<');
if (openIdx == -1) {
return name;
}
StringBuilder buf = new StringBuilder(name.length());
for (int i = 0, depth = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c == '<')
depth++;
else if (c == '>')
depth--;
else if (depth == 0)
buf.append(c);
}
return elements.getName(buf.toString());
}
public static String buildRelativePathFromClassNames(Name contextPackageName, String classPackageName) {
// path, relative to the root, of the destination class
String[] contextClassPath = contextPackageName.toString().split("\\.");
String[] currClassPath = classPackageName.split("\\.");
// compute relative path between the context and the destination
// ... first, compute common part
int i = 0, e = Math.min(contextClassPath.length, currClassPath.length);
while (i < e && contextClassPath[i].equals(currClassPath[i])) {
i++;
}
// ... go up with ".." to reach the common root
StringBuilder buf = new StringBuilder(classPackageName.length());
for (int j = i; j < contextClassPath.length; j++) {
buf.append("../");
}
// ... go down from the common root to the destination
for (int j = i; j < currClassPath.length; j++) {
buf.append(currClassPath[j]).append('/'); // Always use HTML seperators
}
return buf.toString();
}
/**
* We can't just always use the last dot, because there are inner classes. And
* these may have frequent names. But the prime example is
* {@link java.util.Map.Entry}, which we want to show up as package
* <tt>java.util</tt> and class <tt>Map.Entry</tt>.
* <p>
* Note: this is only a heuristic. We only have the string here, and must assume
* users adhere to Java conventions, of beginning package names with a lowercase
* letter.
*
* @param name
* @return Splitting point (Either referring to a dot, or -1)
*/
public static int splitPackageClass(CharSequence name) {
String className = name.toString();
int gen = className.indexOf('<'); // Begin before generics.
int end = gen >= 0 ? gen : className.length();
int start = className.lastIndexOf('.', end);
// No package name special cases:
if (start < 0)
return gen >= 0 || className.isEmpty() ? -1 //
: Character.isLowerCase(className.charAt(0)) ? end : -1;
int split = end;
while (true) {
if (Character.isLowerCase(className.charAt(start + 1)))
return split;
split = start; // Continue, this looks like a class name.
if (start < 0)
return -1;
start = className.lastIndexOf('.', start - 1);
}
}
/**
* Format a double to a string.
* <p>
* Avoids printing "10.0" for exact values like 10.
*
* @param val Value
* @return Formatted value
*/
public static String fmt(double val) {
return val == Math.round(val) ? Long.toString((long) val) : Double.toString(val);
}
}

View File

@ -2,40 +2,40 @@ package org.umlgraph.doclet;
import java.util.regex.Pattern;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.RootDoc;
import jdk.javadoc.doclet.DocletEnvironment;
import javax.lang.model.element.TypeElement;
import org.umlgraph.doclet.util.ElementUtil;
/**
* Matches every class that extends (directly or indirectly) a class
* matched by the regular expression provided.
* Matches every class that extends (directly or indirectly) a class matched by
* the regular expression provided.
*/
public class SubclassMatcher implements ClassMatcher {
protected RootDoc root;
protected DocletEnvironment root;
protected Pattern pattern;
public SubclassMatcher(RootDoc root, Pattern pattern) {
this.root = root;
this.pattern = pattern;
public SubclassMatcher(DocletEnvironment root, Pattern pattern) {
this.root = root;
this.pattern = pattern;
}
public boolean matches(ClassDoc cd) {
// if it's the class we're looking for return
if(pattern.matcher(cd.toString()).matches())
return true;
// recurse on supeclass, if available
if(cd.superclass() != null)
return matches(cd.superclass());
return false;
public boolean matches(TypeElement cd) {
// if it's the class we're looking for return
if (pattern.matcher(cd.toString()).matches()) {
return true;
}
// recurse on superclass, if available
TypeElement scd = ElementUtil.getTypeElement(cd.getSuperclass());
return scd == null ? false : matches(scd);
}
public boolean matches(String name) {
ClassDoc cd = root.classNamed(name);
if(cd == null)
return false;
return matches(cd);
public boolean matches(CharSequence name) {
TypeElement cd = root.getElementUtils().getTypeElement(name);
return cd == null ? false : matches(cd);
}
}

View File

@ -0,0 +1,121 @@
package org.umlgraph.doclet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.umlgraph.doclet.util.CommentHelper;
import com.sun.source.doctree.*;
import com.sun.source.util.SimpleDocTreeVisitor;
/**
* A visitor to gather the block tags found in a comment.
*/
public class TagScanner extends SimpleDocTreeVisitor<Void, Void> {
private final Map<String, List<String>> tags;
public TagScanner(Map<String, List<String>> tags) {
this.tags = tags;
}
@Override
public Void visitDocComment(DocCommentTree tree, Void p) {
if (tree == null) {
return null;
}
String body = CommentHelper.getText(tree.getFullBody());
tags.put("comment", new ArrayList<>(List.of(body)));
return visit(tree.getBlockTags(), null);
}
@Override
public Void visitAuthor(AuthorTree node, Void p) {
String name = node.getTagName();
String content = node.getName().toString();
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitDeprecated(DeprecatedTree node, Void p) {
String name = node.getTagName();
String content = CommentHelper.getText(node.getBody());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitProvides(ProvidesTree node, Void p) {
String name = node.getTagName();
String content = CommentHelper.getText(node.getDescription());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitSince(SinceTree node, Void p) {
String name = node.getTagName();
String content = CommentHelper.getText(node.getBody());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitVersion(VersionTree node, Void p) {
String name = node.getTagName();
String content = CommentHelper.getText(node.getBody());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitParam(ParamTree node, Void p) {
String name = node.getTagName();
String content = node.getName().toString() + " " + CommentHelper.getText(node.getDescription());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitReturn(ReturnTree node, Void p) {
String name = node.getTagName();
String content = CommentHelper.getText(node.getDescription());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitSee(SeeTree node, Void p) {
String name = node.getTagName();
String content = CommentHelper.getText(node.getReference());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitThrows(ThrowsTree node, Void p) {
String name = node.getTagName();
String content = CommentHelper.getText(node.getDescription());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitUses(UsesTree node, Void p) {
String name = node.getTagName();
String content = CommentHelper.getText(node.getDescription());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
@Override
public Void visitUnknownBlockTag(UnknownBlockTagTree tree, Void p) {
String name = tree.getTagName();
String content = CommentHelper.getText(tree.getContent());
tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content);
return null;
}
}

View File

@ -2,8 +2,10 @@ package org.umlgraph.doclet;
/**
* Options for UMLGraph class diagram generation
*
* @opt operations
* @opt visibility
* @hidden
*/
public class UMLOptions {}
public class UMLOptions {
}

View File

@ -20,17 +20,30 @@
package org.umlgraph.doclet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.Doc;
import com.sun.javadoc.LanguageVersion;
import com.sun.javadoc.RootDoc;
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;
import jdk.javadoc.doclet.StandardDoclet;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import org.umlgraph.doclet.util.ElementUtil;
import org.umlgraph.doclet.util.TagUtil;
/**
* Doclet API implementation
*
* @depend - - - OptionProvider
* @depend - - - Options
* @depend - - - View
@ -40,7 +53,7 @@ import com.sun.javadoc.RootDoc;
* @version $Revision$
* @author <a href="http://www.spinellis.gr">Diomidis Spinellis</a>
*/
public class UmlGraph {
public class UmlGraph implements Doclet {
private static final String programName = "UmlGraph";
private static final String docletName = "org.umlgraph.doclet.UmlGraph";
@ -48,139 +61,197 @@ public class UmlGraph {
/** Options used for commenting nodes */
private static Options commentOptions;
/** Entry point through javadoc */
public static boolean start(RootDoc root) throws IOException {
Options opt = buildOptions(root);
root.printNotice("UMLGraph doclet version " + Version.VERSION + " started");
View[] views = buildViews(opt, root, root);
if(views == null)
return false;
if (views.length == 0)
buildGraph(root, opt, null);
else
for (int i = 0; i < views.length; i++)
buildGraph(root, views[i], null);
return true;
private Locale locale;
private Reporter reporter;
private Options options;
private StandardDoclet standard;
public UmlGraph() {
this.options = new Options();
this.standard = new StandardDoclet();
}
public static void main(String args[]) {
PrintWriter err = new PrintWriter(System.err);
com.sun.tools.javadoc.Main.execute(programName,
err, err, err, docletName, args);
@Override
public void init(Locale locale, Reporter reporter) {
this.locale = locale;
this.reporter = reporter;
}
public static Options getCommentOptions() {
return commentOptions;
@Override
public String getName() {
return docletName;
}
@Override
public Set<? extends Doclet.Option> getSupportedOptions() {
Set<Doclet.Option> options = new HashSet<>(standard.getSupportedOptions());
for (Doclet.Option opt : this.options.OPTIONS) {
options.add(opt);
}
return options;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return standard.getSupportedSourceVersion();
}
/**
* Creates the base Options object.
* This contains both the options specified on the command
* line and the ones specified in the UMLOptions class, if available.
* Also create the globally accessible commentOptions object.
* Standard doclet entry point
*
* @param root
* @return
*/
public static Options buildOptions(RootDoc root) {
commentOptions = new Options();
commentOptions.setOptions(root.options());
commentOptions.setOptions(findClass(root, "UMLNoteOptions"));
commentOptions.shape = new Shape("note");
@Override
/** Entry point through javadoc */
public boolean run(DocletEnvironment root) {
reporter.print(Diagnostic.Kind.NOTE, "UMLGraph doclet version " + Version.VERSION + " started");
Options opt = new Options();
opt.setOptions(root.options());
opt.setOptions(findClass(root, "UMLOptions"));
return opt;
List<View> views = buildViews(options, root, root);
if (views == null) {
return false;
}
try {
if (views.isEmpty()) {
buildGraph(reporter, root, options, null, null);
} else {
for (View view : views) {
buildGraph(reporter, root, options, view, null);
}
}
} catch (IOException ioe) {
reporter.print(Diagnostic.Kind.ERROR, "UMLGraph doclet error : " + ioe);
}
return true;
}
public static Options getCommentOptions() {
return commentOptions;
}
/**
* Creates the base Options object. This contains both the options specified on
* the command line and the ones specified in the UMLOptions class, if
* available. Also create the globally accessible commentOptions object.
*/
public static Options buildOptions(DocletEnvironment root, Options o) {
commentOptions = o.clone();
commentOptions.setOptions(root.getDocTrees(), findClass(root, "UMLNoteOptions", false));
commentOptions.shape = Shape.NOTE;
Options opt = o.clone();
opt.setOptions(root.getDocTrees(), findClass(root, "UMLOptions", false));
return opt;
}
/** Return the ClassDoc for the specified class; null if not found. */
private static ClassDoc findClass(RootDoc root, String name) {
ClassDoc[] classes = root.classes();
for (ClassDoc cd : classes)
if(cd.name().equals(name))
return cd;
return null;
private static TypeElement findClass(DocletEnvironment root, String name, boolean qualified) {
Set<? extends Element> classes = root.getIncludedElements();
for (Element element : classes) {
if (qualified && element instanceof TypeElement && ((TypeElement) element).getQualifiedName().toString().equals(name)) {
return (TypeElement) element;
} else if (!qualified && element instanceof TypeElement && element.getSimpleName().toString().equals(name)) {
return (TypeElement) element;
}
}
return null;
}
/**
* Builds and outputs a single graph according to the view overrides
*/
public static void buildGraph(RootDoc root, OptionProvider op, Doc contextDoc) throws IOException {
if(getCommentOptions() == null)
buildOptions(root);
Options opt = op.getGlobalOptions();
root.printNotice("Building " + op.getDisplayName());
ClassDoc[] classes = root.classes();
public static void buildGraph(Reporter reporter, DocletEnvironment root, Options options, OptionProvider op, Element contextDoc) throws IOException {
if (getCommentOptions() == null) {
buildOptions(root, options);
}
Options opt = op.getGlobalOptions();
reporter.print(Diagnostic.Kind.NOTE, "Building " + op.getDisplayName());
Set<? extends Element> elements = root.getIncludedElements();
Set<TypeElement> classes = new HashSet<>();
for (Element element : elements) {
if (element instanceof TypeElement) {
classes.add((TypeElement) element);
}
}
ClassGraph c = new ClassGraph(root, op, contextDoc);
c.prologue();
for (int i = 0; i < classes.length; i++)
c.printClass(classes[i], true);
for (int i = 0; i < classes.length; i++)
c.printRelations(classes[i]);
if(opt.inferRelationships)
c.printInferredRelations(classes);
if(opt.inferDependencies)
c.printInferredDependencies(classes);
ClassGraph c = new ClassGraph(root, op, contextDoc);
c.prologue();
for (TypeElement cd : classes) {
c.printClass(cd, true);
}
for (TypeElement cd : classes) {
c.printRelations(cd);
}
if (opt.inferRelationships) {
for (TypeElement cd : classes) {
c.printInferredRelations(cd);
}
}
if (opt.inferDependencies) {
for (TypeElement cd : classes) {
c.printInferredDependencies(cd);
}
}
c.printExtraClasses(root);
c.epilogue();
c.printExtraClasses(root);
c.epilogue();
}
/**
* Builds the views according to the parameters on the command line
* @param opt The options
* @param srcRootDoc The RootDoc for the source classes
* @param viewRootDoc The RootDoc for the view classes (may be
* different, or may be the same as the srcRootDoc)
*
* @param opt The options
* @param srcRootDoc The RootDoc for the source classes
* @param viewRootDoc The RootDoc for the view classes (may be different, or may
* be the same as the srcRootDoc)
*/
public static View[] buildViews(Options opt, RootDoc srcRootDoc, RootDoc viewRootDoc) {
if (opt.viewName != null) {
ClassDoc viewClass = viewRootDoc.classNamed(opt.viewName);
if(viewClass == null) {
System.out.println("View " + opt.viewName + " not found! Exiting without generating any output.");
return null;
}
if(viewClass.tags("view").length == 0) {
System.out.println(viewClass + " is not a view!");
return null;
}
if(viewClass.isAbstract()) {
System.out.println(viewClass + " is an abstract view, no output will be generated!");
return null;
}
return new View[] { buildView(srcRootDoc, viewClass, opt) };
} else if (opt.findViews) {
List<View> views = new ArrayList<View>();
ClassDoc[] classes = viewRootDoc.classes();
public static List<View> buildViews(Options opt, DocletEnvironment srcRootDoc, DocletEnvironment viewRootDoc) {
if (opt.viewName != null) {
TypeElement viewClass = findClass(viewRootDoc, opt.viewName, true);
if (viewClass == null) {
System.out.println("View " + opt.viewName + " not found! Exiting without generating any output.");
return null;
}
if (TagUtil.getTag(viewRootDoc, viewClass, "view").isEmpty()) {
System.out.println(viewClass + " is not a view!");
return null;
}
if (viewClass.getModifiers().contains(Modifier.ABSTRACT)) {
System.out.println(viewClass + " is an abstract view, no output will be generated!");
return null;
}
return List.of(buildView(srcRootDoc, viewClass, opt));
} else if (opt.findViews) {
List<View> views = new ArrayList<>();
Set<? extends Element> classes = viewRootDoc.getIncludedElements();
// find view classes
for (int i = 0; i < classes.length; i++)
if (classes[i].tags("view").length > 0 && !classes[i].isAbstract())
views.add(buildView(srcRootDoc, classes[i], opt));
// find view classes
for (Element elmt : classes) {
if (!(elmt instanceof TypeElement)) {
continue;
}
TypeElement element = (TypeElement) elmt;
if (TagUtil.getTag(viewRootDoc, element, "view").size() > 0 && !element.getModifiers().contains(Modifier.ABSTRACT)) {
views.add(buildView(srcRootDoc, element, opt));
}
}
return views.toArray(new View[views.size()]);
} else
return new View[0];
return views;
} else {
return Collections.emptyList();
}
}
/**
* Builds a view along with its parent views, recursively
*/
private static View buildView(RootDoc root, ClassDoc viewClass, OptionProvider provider) {
ClassDoc superClass = viewClass.superclass();
if(superClass == null || superClass.tags("view").length == 0)
return new View(root, viewClass, provider);
private static View buildView(DocletEnvironment root, TypeElement viewClass, OptionProvider provider) {
TypeElement superClass = ElementUtil.getSuperclass(viewClass);
if (superClass == null || TagUtil.getTag(root, superClass, "view").isEmpty()) {
return new View(root, viewClass, provider);
}
return new View(root, viewClass, buildView(root, superClass, provider));
}
/** Option checking */
public static int optionLength(String option) {
return Options.optionLength(option);
}
/** Indicate the language version we support */
public static LanguageVersion languageVersion() {
return LanguageVersion.JAVA_1_5;
return new View(root, viewClass, buildView(root, superClass, provider));
}
}

View File

@ -3,284 +3,287 @@ package org.umlgraph.doclet;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.TreeSet;
import java.io.OutputStreamWriter;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.LanguageVersion;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.RootDoc;
import com.sun.tools.doclets.standard.Standard;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import org.umlgraph.doclet.util.ElementUtil;
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;
import jdk.javadoc.doclet.StandardDoclet;
/**
* Chaining doclet that runs the standart Javadoc doclet first, and on success,
* runs the generation of dot files by UMLGraph
*
* @author wolf
*
* @depend - - - WrappedClassDoc
* @depend - - - WrappedRootDoc
*/
public class UmlGraphDoc {
/**
* Option check, forwards options to the standard doclet, if that one refuses them,
* they are sent to UmlGraph
*/
public static int optionLength(String option) {
int result = Standard.optionLength(option);
if (result != 0)
return result;
else
return UmlGraph.optionLength(option);
public class UmlGraphDoc implements Doclet {
private Locale locale;
private Reporter reporter;
private Options options;
private StandardDoclet standard;
public UmlGraphDoc() {
this.options = new Options();
this.standard = new StandardDoclet();
}
@Override
public void init(Locale locale, Reporter reporter) {
this.locale = locale;
this.reporter = reporter;
this.standard.init(locale, reporter);
}
@Override
public String getName() {
return this.getClass().getSimpleName();
}
@Override
public Set<? extends Doclet.Option> getSupportedOptions() {
Set<Doclet.Option> options = new HashSet<>(standard.getSupportedOptions());
for (Doclet.Option opt : this.options.OPTIONS) {
options.add(opt);
}
return options;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return standard.getSupportedSourceVersion();
}
/**
* Standard doclet entry point
*
* @param root
* @return
*/
public static boolean start(RootDoc root) {
root.printNotice("UmlGraphDoc version " + Version.VERSION + ", running the standard doclet");
Standard.start(root);
root.printNotice("UmlGraphDoc version " + Version.VERSION + ", altering javadocs");
try {
String outputFolder = findOutputPath(root.options());
@Override
public boolean run(DocletEnvironment root) {
reporter.print(Diagnostic.Kind.NOTE, "UmlGraphDoc version " + Version.VERSION + ", running the standard doclet");
standard.run(root);
reporter.print(Diagnostic.Kind.NOTE, "UmlGraphDoc version " + Version.VERSION + ", altering javadocs");
try {
Options opt = UmlGraph.buildOptions(root, this.options);
// in javadoc enumerations are always printed
opt.showEnumerations = true;
opt.relativeLinksForSourcePackages = true;
// enable strict matching for hide expressions
opt.strictMatching = true;
reporter.print(Diagnostic.Kind.NOTE, opt.toString());
Options opt = UmlGraph.buildOptions(root);
opt.setOptions(root.options());
// in javadoc enumerations are always printed
opt.showEnumerations = true;
opt.relativeLinksForSourcePackages = true;
// enable strict matching for hide expressions
opt.strictMatching = true;
// root.printNotice(opt.toString());
root = new WrappedRootDoc(root);
generatePackageDiagrams(root, opt, outputFolder);
generateContextDiagrams(root, opt, outputFolder);
} catch(Throwable t) {
root.printWarning("Error!");
root.printWarning(t.toString());
t.printStackTrace();
return false;
}
return true;
generatePackageDiagrams(root, reporter, opt, this.options.outputDirectory);
generateContextDiagrams(root, reporter, opt, this.options.outputDirectory);
} catch (Throwable t) {
reporter.print(Diagnostic.Kind.WARNING, "Error: " + t.toString());
t.printStackTrace();
return false;
}
return true;
}
/**
* Standand doclet entry
* @return
* Generates the package diagrams for all of the packages that contain classes
* among those returned by RootDoc.class()
*/
public static LanguageVersion languageVersion() {
return Standard.languageVersion();
}
/**
* Generates the package diagrams for all of the packages that contain classes among those
* returned by RootDoc.class()
*/
private static void generatePackageDiagrams(RootDoc root, Options opt, String outputFolder)
throws IOException {
Set<String> packages = new HashSet<String>();
for (ClassDoc classDoc : root.classes()) {
PackageDoc packageDoc = classDoc.containingPackage();
if(!packages.contains(packageDoc.name())) {
packages.add(packageDoc.name());
OptionProvider view = new PackageView(outputFolder, packageDoc, root, opt);
UmlGraph.buildGraph(root, view, packageDoc);
runGraphviz(opt.dotExecutable, outputFolder, packageDoc.name(), packageDoc.name(), root);
alterHtmlDocs(opt, outputFolder, packageDoc.name(), packageDoc.name(),
"package-summary.html", Pattern.compile("(</[Hh]2>)|(<h1 title=\"Package\").*"), root);
}
}
private static void generatePackageDiagrams(DocletEnvironment root, Reporter reporter, Options opt, String outputFolder) throws IOException {
Set<Name> packages = new HashSet<>();
for (Element classDoc : root.getIncludedElements()) {
PackageElement packageDoc = null;
if (classDoc instanceof PackageElement) {
packageDoc = (PackageElement) classDoc;
} else if (classDoc instanceof TypeElement) {
packageDoc = ElementUtil.getPackageOf(root, classDoc);
} else {
continue;
}
if (!packages.contains(packageDoc.getQualifiedName())) {
packages.add(packageDoc.getQualifiedName());
OptionProvider view = new PackageView(outputFolder, packageDoc, root, opt);
UmlGraph.buildGraph(reporter, root, opt, view, packageDoc);
runGraphviz(opt.dotExecutable, outputFolder, ElementUtil.getModuleOf(root, packageDoc), packageDoc.getQualifiedName(), packageDoc.getSimpleName(), reporter);
alterHtmlDocs(opt, outputFolder, ElementUtil.getModuleOf(root, packageDoc), packageDoc.getQualifiedName(), packageDoc.getSimpleName(), "package-summary.html",
Pattern.compile("(</[Hh]2>)|(<h1 title=\"Package( |\")).*"), reporter);
}
}
}
/**
* Generates the context diagram for a single class
*/
private static void generateContextDiagrams(RootDoc root, Options opt, String outputFolder)
throws IOException {
Set<ClassDoc> classDocs = new TreeSet<ClassDoc>(new Comparator<ClassDoc>() {
public int compare(ClassDoc cd1, ClassDoc cd2) {
return cd1.name().compareTo(cd2.name());
private static void generateContextDiagrams(DocletEnvironment root, Reporter reporter, Options opt, String outputFolder) throws IOException {
Set<TypeElement> classDocs = new TreeSet<>(new Comparator<>() {
public int compare(TypeElement cd1, TypeElement cd2) {
return cd1.getSimpleName().toString().compareTo(cd2.getSimpleName().toString());
}
});
for (ClassDoc classDoc : root.classes())
classDocs.add(classDoc);
for (Element classDoc : root.getIncludedElements()) {
if (classDoc instanceof TypeElement) {
classDocs.add((TypeElement) classDoc);
}
}
ContextView view = null;
for (ClassDoc classDoc : classDocs) {
if(view == null)
view = new ContextView(outputFolder, classDoc, root, opt);
else
view.setContextCenter(classDoc);
UmlGraph.buildGraph(root, view, classDoc);
runGraphviz(opt.dotExecutable, outputFolder, classDoc.containingPackage().name(), classDoc.name(), root);
alterHtmlDocs(opt, outputFolder, classDoc.containingPackage().name(), classDoc.name(),
classDoc.name() + ".html", Pattern.compile(".*(Class|Interface|Enum) " + classDoc.name() + ".*") , root);
}
ContextView view = null;
for (TypeElement classDoc : classDocs) {
try {
if (view == null) {
view = new ContextView(outputFolder, classDoc, root, opt);
} else {
view.setContextCenter(classDoc);
}
UmlGraph.buildGraph(reporter, root, opt, view, classDoc);
runGraphviz(opt.dotExecutable, outputFolder, ElementUtil.getModuleOf(root, classDoc), ElementUtil.getPackageOf(root, classDoc).getQualifiedName(), classDoc.getSimpleName(), reporter);
alterHtmlDocs(opt, outputFolder, ElementUtil.getModuleOf(root, classDoc), ElementUtil.getPackageOf(root, classDoc).getQualifiedName(), classDoc.getSimpleName(),
classDoc.getSimpleName() + ".html",
Pattern.compile(".*(Class|Interface|Enum) " + classDoc.getSimpleName() + ".*"), reporter);
} catch (Exception e) {
throw new RuntimeException("Error generating " + classDoc.getSimpleName(), e);
}
}
}
/**
* Runs Graphviz dot building both a diagram (in png format) and a client side map for it.
* Runs Graphviz dot building both a diagram (in png format) and a client side
* map for it.
*/
private static void runGraphviz(String dotExecutable, String outputFolder, String packageName, String name, RootDoc root) {
if (dotExecutable == null) {
dotExecutable = "dot";
}
File dotFile = new File(outputFolder, packageName.replace(".", "/") + "/" + name + ".dot");
File pngFile = new File(outputFolder, packageName.replace(".", "/") + "/" + name + ".png");
File mapFile = new File(outputFolder, packageName.replace(".", "/") + "/" + name + ".map");
private static void runGraphviz(String dotExecutable, String outputFolder, ModuleElement module, Name packageName, Name name, Reporter reporter) {
if (dotExecutable == null) {
dotExecutable = "dot";
}
String fileName = packageName.toString().replace(".", "/") + "/" + name;
if (Runtime.version().major() > 10 && module != null) {
fileName = module.getQualifiedName().toString() + '/' + fileName;
}
File dotFile = new File(outputFolder, fileName + ".dot");
File svgFile = new File(outputFolder, fileName + ".svg");
try {
Process p = Runtime.getRuntime().exec(new String [] {
dotExecutable,
"-Tcmapx",
"-o",
mapFile.getAbsolutePath(),
"-Tpng",
"-o",
pngFile.getAbsolutePath(),
dotFile.getAbsolutePath()
});
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = null;
while((line = reader.readLine()) != null)
root.printWarning(line);
int result = p.waitFor();
if (result != 0)
root.printWarning("Errors running Graphviz on " + dotFile);
} catch (Exception e) {
e.printStackTrace();
System.err.println("Ensure that dot is in your path and that its path does not contain spaces");
}
try {
Process p = Runtime.getRuntime().exec(new String[] { dotExecutable, "-Tsvg", "-o",
svgFile.getAbsolutePath(), dotFile.getAbsolutePath() });
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line;
while ((line = reader.readLine()) != null) {
reporter.print(Diagnostic.Kind.WARNING, line);
}
int result = p.waitFor();
if (result != 0) {
reporter.print(Diagnostic.Kind.WARNING, "Errors running Graphviz on " + dotFile);
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("Ensure that dot is in your path and that its path does not contain spaces");
}
}
//Format string for the uml image div tag.
private static final String UML_DIV_TAG =
"<div align=\"center\">" +
"<img src=\"%1$s.png\" alt=\"Package class diagram package %1$s\" usemap=\"#G\" border=0/>" +
"</div>";
//Format string for the java script tag.
private static final String EXPANDABLE_UML =
"<script type=\"text/javascript\">\n" +
"function show() {\n" +
" document.getElementById(\"uml\").innerHTML = \n" +
" \'<a style=\"font-family:monospace\" href=\"javascript:hide()\">%3$s</a>\' +\n" +
" \'%1$s\';\n" +
"}\n" +
"function hide() {\n" +
" document.getElementById(\"uml\").innerHTML = \n" +
" \'<a style=\"font-family:monospace\" href=\"javascript:show()\">%2$s</a>\' ;\n" +
"}\n" +
"</script>\n" +
"<div id=\"uml\" >\n" +
" <a href=\"javascript:show()\">\n" +
" <a style=\"font-family:monospace\" href=\"javascript:show()\">%2$s</a> \n" +
"</div>";
/**
* Takes an HTML file, looks for the first instance of the specified insertion point, and
* inserts the diagram image reference and a client side map in that point.
*/
private static void alterHtmlDocs(Options opt, String outputFolder, String packageName, String className,
String htmlFileName, Pattern insertPointPattern, RootDoc root) throws IOException {
// setup files
File output = new File(outputFolder, packageName.replace(".", "/"));
File htmlFile = new File(output, htmlFileName);
File alteredFile = new File(htmlFile.getAbsolutePath() + ".uml");
File mapFile = new File(output, className + ".map");
if (!htmlFile.exists()) {
System.err.println("Expected file not found: " + htmlFile.getAbsolutePath());
return;
}
// Format string for the uml image div tag.
private static final String UML_DIV_TAG = "<div align=\"center\">"
+ "<object width=\"100%%\" height=\"100%%\" type=\"image/svg+xml\" data=\"%1$s.svg\" alt=\"Package class diagram package %1$s\" border=0></object>"
+ "</div>";
// parse & rewrite
BufferedWriter writer = null;
BufferedReader reader = null;
boolean matched = false;
try {
writer = new BufferedWriter(new OutputStreamWriter(new
FileOutputStream(alteredFile), opt.outputEncoding));
reader = new BufferedReader(new InputStreamReader(new
FileInputStream(htmlFile), opt.outputEncoding));
private static final String UML_AUTO_SIZED_DIV_TAG = "<div align=\"center\">"
+ "<object type=\"image/svg+xml\" data=\"%1$s.svg\" alt=\"Package class diagram package %1$s\" border=0></object>"
+ "</div>";
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
if (!matched && insertPointPattern.matcher(line).matches()) {
matched = true;
if (mapFile.exists())
insertClientSideMap(mapFile, writer);
else
root.printWarning("Could not find map file " + mapFile);
String tag = String.format(UML_DIV_TAG, className);
if (opt.collapsibleDiagrams)
tag = String.format(EXPANDABLE_UML, tag, "Show UML class diagram", "Hide UML class diagram");
writer.write("<!-- UML diagram added by UMLGraph version " +
Version.VERSION +
" (http://www.umlgraph.org/) -->");
writer.newLine();
writer.write(tag);
writer.newLine();
}
}
} finally {
if (writer != null)
writer.close();
if (reader != null)
reader.close();
}
private static final String EXPANDABLE_UML_STYLE = "font-family: Arial,Helvetica,sans-serif;font-size: 1.5em; display: block; width: 250px; height: 20px; background: #009933; padding: 5px; text-align: center; border-radius: 8px; color: white; font-weight: bold;";
// if altered, delete old file and rename new one to the old file name
if (matched) {
htmlFile.delete();
alteredFile.renameTo(htmlFile);
} else {
root.printNotice("Warning, could not find a line that matches the pattern '" + insertPointPattern.pattern()
+ "'.\n Class diagram reference not inserted");
alteredFile.delete();
}
}
// Format string for the java script tag.
private static final String EXPANDABLE_UML = "<script type=\"text/javascript\">\n" + "function show() {\n"
+ " document.getElementById(\"uml\").innerHTML = \n" + " \'<a style=\"" + EXPANDABLE_UML_STYLE
+ "\" href=\"javascript:hide()\">%3$s</a>\' +\n" + " \'%1$s\';\n" + "}\n" + "function hide() {\n"
+ " document.getElementById(\"uml\").innerHTML = \n" + " \'<a style=\"" + EXPANDABLE_UML_STYLE
+ "\" href=\"javascript:show()\">%2$s</a>\' ;\n" + "}\n" + "</script>\n" + "<div id=\"uml\" >\n"
+ " <a href=\"javascript:show()\">\n" + " <a style=\"" + EXPANDABLE_UML_STYLE
+ "\" href=\"javascript:show()\">%2$s</a> \n" + "</div>";
/**
* Reads the map file and outputs in to the specified writer
* @throws IOException
* Takes an HTML file, looks for the first instance of the specified insertion
* point, and inserts the diagram image reference and a client side map in that
* point.
*/
private static void insertClientSideMap(File mapFile, BufferedWriter writer) throws IOException {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(mapFile));
String line = null;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
}
} finally {
if (reader != null)
reader.close();
}
}
private static void alterHtmlDocs(Options opt, String outputFolder, ModuleElement module, Name packageName, Name className,
String htmlFileName, Pattern insertPointPattern, Reporter reporter) throws IOException {
// setup files
String prefix = Runtime.version().major() > 10 && module != null ? module.getQualifiedName().toString() + '/' : "";
File output = new File(outputFolder, prefix + packageName.toString().replace(".", "/"));
File htmlFile = new File(output, htmlFileName);
File alteredFile = new File(htmlFile.getAbsolutePath() + ".uml");
if (!htmlFile.exists()) {
System.err.println("Expected file not found: " + htmlFile.getAbsolutePath());
return;
}
/**
* Returns the output path specified on the javadoc options
*/
private static String findOutputPath(String[][] options) {
for (int i = 0; i < options.length; i++) {
if (options[i][0].equals("-d"))
return options[i][1];
}
return ".";
// parse & rewrite
BufferedWriter writer = null;
BufferedReader reader = null;
boolean matched = false;
try {
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(alteredFile), opt.outputEncoding));
reader = new BufferedReader(new InputStreamReader(new FileInputStream(htmlFile), opt.outputEncoding));
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
if (!matched && insertPointPattern.matcher(line).matches()) {
matched = true;
String tag;
if (opt.autoSize) {
tag = String.format(UML_AUTO_SIZED_DIV_TAG, className);
} else {
tag = String.format(UML_DIV_TAG, className);
}
if (opt.collapsibleDiagrams) {
tag = String.format(EXPANDABLE_UML, tag, "Show UML class diagram", "Hide UML class diagram");
}
writer.write("<!-- UML diagram added by UMLGraph version " + Version.VERSION + " (http://www.spinellis.gr/umlgraph/) -->");
writer.newLine();
writer.write(tag);
writer.newLine();
}
}
} finally {
if (writer != null) {
writer.close();
}
if (reader != null) {
reader.close();
}
}
// if altered, delete old file and rename new one to the old file name
if (matched) {
htmlFile.delete();
alteredFile.renameTo(htmlFile);
} else {
reporter.print(Diagnostic.Kind.NOTE, "Warning, could not find a line that matches the pattern '"
+ insertPointPattern.pattern() + "'.\n Class diagram reference not inserted");
alteredFile.delete();
}
}
}

View File

@ -0,0 +1,6 @@
/* Automatically generated file */
package org.umlgraph.doclet;
class Version {
public static String VERSION = "R5_7_2-60-g0e99a6";
}

View File

@ -23,15 +23,19 @@ import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.Tag;
import javax.lang.model.element.TypeElement;
import org.umlgraph.doclet.util.TagUtil;
import jdk.javadoc.doclet.DocletEnvironment;
import com.sun.source.util.DocTrees;
/**
* Contains the definition of a View. A View is a set of option overrides that
* will lead to the creation of a UML class diagram. Multiple views can be
* defined on the same source tree, effectively allowing to create multiple
* class diagram out of it.
*
* @author wolf
*
* @depend - - - Options
@ -43,137 +47,137 @@ import com.sun.javadoc.Tag;
*
*/
public class View implements OptionProvider {
Map<ClassMatcher, List<String[]>> optionOverrides = new LinkedHashMap<ClassMatcher, List<String[]>>();
ClassDoc viewDoc;
Map<ClassMatcher, List<String[]>> optionOverrides = new LinkedHashMap<>();
TypeElement viewDoc;
OptionProvider provider;
List<String[]> globalOptions;
RootDoc root;
DocletEnvironment root;
/**
* Builds a view given the class that contains its definition
*/
public View(RootDoc root, ClassDoc c, OptionProvider provider) {
this.viewDoc = c;
this.provider = provider;
this.root = root;
Tag[] tags = c.tags();
ClassMatcher currMatcher = null;
// parse options, get the global ones, and build a map of the
// pattern matched overrides
globalOptions = new ArrayList<String[]>();
for (int i = 0; i < tags.length; i++) {
if (tags[i].name().equals("@match")) {
currMatcher = buildMatcher(tags[i].text());
if(currMatcher != null) {
optionOverrides.put(currMatcher, new ArrayList<String[]>());
}
} else if (tags[i].name().equals("@opt")) {
String[] opts = StringUtil.tokenize(tags[i].text());
opts[0] = "-" + opts[0];
if (currMatcher == null) {
globalOptions.add(opts);
} else {
optionOverrides.get(currMatcher).add(opts);
}
}
}
public View(DocletEnvironment root, TypeElement c, OptionProvider provider) {
this.viewDoc = c;
this.provider = provider;
this.root = root;
Map<String, List<String>> tags = TagUtil.getTags(root, viewDoc);
ClassMatcher currMatcher = null;
// parse options, get the global ones, and build a map of the
// pattern matched overrides
globalOptions = new ArrayList<String[]>();
if (tags.get("match") != null) {
for (String text : tags.get("match")) {
currMatcher = buildMatcher(text);
if (currMatcher != null) {
optionOverrides.put(currMatcher, new ArrayList<>());
}
}
}
if (tags.get("opt") != null) {
for (String text : tags.get("opt")) {
String[] opts = StringUtil.tokenize(text);
opts[0] = "-" + opts[0];
if (currMatcher == null) {
globalOptions.add(opts);
} else {
optionOverrides.get(currMatcher).add(opts);
}
}
}
}
/**
* Factory method that builds the appropriate matcher for @match tags
*/
private ClassMatcher buildMatcher(String tagText) {
// check there are at least @match <type> and a parameter
String[] strings = StringUtil.tokenize(tagText);
if (strings.length < 2) {
System.err.println("Skipping uncomplete @match tag, type missing: " + tagText + " in view " + viewDoc);
return null;
}
try {
if (strings[0].equals("class")) {
return new PatternMatcher(Pattern.compile(strings[1]));
} else if (strings[0].equals("context")) {
return new ContextMatcher(root, Pattern.compile(strings[1]), getGlobalOptions(),
false);
} else if (strings[0].equals("outgoingContext")) {
return new ContextMatcher(root, Pattern.compile(strings[1]), getGlobalOptions(),
false);
} else if (strings[0].equals("interface")) {
return new InterfaceMatcher(root, Pattern.compile(strings[1]));
} else if (strings[0].equals("subclass")) {
return new SubclassMatcher(root, Pattern.compile(strings[1]));
} else {
System.err.println("Skipping @match tag, unknown match type, in view " + viewDoc);
}
} catch (PatternSyntaxException pse) {
System.err.println("Skipping @match tag due to invalid regular expression '" + tagText
+ "'" + " in view " + viewDoc);
} catch (Exception e) {
System.err.println("Skipping @match tag due to an internal error '" + tagText
+ "'" + " in view " + viewDoc);
e.printStackTrace();
}
return null;
}
// check there are at least @match <type> and a parameter
String[] strings = StringUtil.tokenize(tagText);
if (strings.length < 2) {
System.err.println("Skipping uncomplete @match tag, type missing: " + tagText + " in view " + viewDoc);
return null;
}
// ----------------------------------------------------------------
try {
if (strings[0].equals("class")) {
return new PatternMatcher(Pattern.compile(strings[1]));
} else if (strings[0].equals("context")) {
return new ContextMatcher(root, Pattern.compile(strings[1]), getGlobalOptions(), false);
} else if (strings[0].equals("outgoingContext")) {
return new ContextMatcher(root, Pattern.compile(strings[1]), getGlobalOptions(), false);
} else if (strings[0].equals("interface")) {
return new InterfaceMatcher(root, Pattern.compile(strings[1]));
} else if (strings[0].equals("subclass")) {
return new SubclassMatcher(root, Pattern.compile(strings[1]));
} else {
System.err.println("Skipping @match tag, unknown match type, in view " + viewDoc);
}
} catch (PatternSyntaxException pse) {
System.err.println("Skipping @match tag due to invalid regular expression '" + tagText + "'" + " in view " + viewDoc);
} catch (Exception e) {
System.err.println("Skipping @match tag due to an internal error '" + tagText + "'" + " in view " + viewDoc);
e.printStackTrace();
}
return null;
}
// ----------------------------------------------------------------
// OptionProvider methods
// ----------------------------------------------------------------
// ----------------------------------------------------------------
public Options getOptionsFor(ClassDoc cd) {
Options localOpt = getGlobalOptions();
overrideForClass(localOpt, cd);
localOpt.setOptions(cd);
return localOpt;
public Options getOptionsFor(DocTrees dt, TypeElement cd) {
Options localOpt = getGlobalOptions();
overrideForClass(localOpt, cd);
localOpt.setOptions(dt, cd);
return localOpt;
}
public Options getOptionsFor(String name) {
Options localOpt = getGlobalOptions();
overrideForClass(localOpt, name);
return localOpt;
public Options getOptionsFor(CharSequence name) {
Options localOpt = getGlobalOptions();
overrideForClass(localOpt, name);
return localOpt;
}
public Options getGlobalOptions() {
Options go = provider.getGlobalOptions();
boolean outputSet = false;
for (String[] opts : globalOptions) {
if (opts[0].equals("-output"))
outputSet = true;
go.setOption(opts);
}
if (!outputSet)
go.setOption(new String[] { "-output", viewDoc.name() + ".dot" });
return go;
Options go = provider.getGlobalOptions();
boolean outputSet = false;
for (String[] opts : globalOptions) {
if (Options.matchOption(opts[0], "output")) {
outputSet = true;
}
go.setOption(opts);
}
if (!outputSet) {
go.setOption(new String[] { "output", viewDoc.getSimpleName() + ".dot" });
}
return go;
}
public void overrideForClass(Options opt, ClassDoc cd) {
provider.overrideForClass(opt, cd);
for (ClassMatcher cm : optionOverrides.keySet()) {
if(cm.matches(cd)) {
for (String[] override : optionOverrides.get(cm)) {
opt.setOption(override);
}
}
}
public void overrideForClass(Options opt, TypeElement cd) {
provider.overrideForClass(opt, cd);
for (ClassMatcher cm : optionOverrides.keySet()) {
if (cm.matches(cd)) {
for (String[] override : optionOverrides.get(cm)) {
opt.setOption(override);
}
}
}
}
public void overrideForClass(Options opt, String className) {
provider.overrideForClass(opt, className);
for (ClassMatcher cm : optionOverrides.keySet()) {
if(cm.matches(className)) {
for (String[] override : optionOverrides.get(cm)) {
opt.setOption(override);
}
}
}
public void overrideForClass(Options opt, CharSequence className) {
provider.overrideForClass(opt, className);
for (ClassMatcher cm : optionOverrides.keySet()) {
if (cm.matches(className)) {
for (String[] override : optionOverrides.get(cm)) {
opt.setOption(override);
}
}
}
}
public String getDisplayName() {
return "view " + viewDoc.name();
return "view " + viewDoc.getSimpleName();
}
}

View File

@ -18,26 +18,36 @@
*/
package org.umlgraph.doclet;
import com.sun.javadoc.ProgramElementDoc;
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
/**
* Enumerates the possible visibilities in a Java program. For brevity, package
* private visibility is referred as PACKAGE.
* @author wolf
*
* @author wolf
*/
public enum Visibility {
PRIVATE, PACKAGE, PROTECTED, PUBLIC;
PRIVATE("- "), PACKAGE("~ "), PROTECTED("# "), PUBLIC("+ ");
public static Visibility get(ProgramElementDoc doc) {
if (doc.isPrivate())
return PRIVATE;
else if (doc.isPackagePrivate())
return PACKAGE;
else if (doc.isProtected())
return PROTECTED;
else
return PUBLIC;
final public String symbol;
private Visibility(String symbol) {
this.symbol = symbol;
}
}
public static Visibility get(Element doc) {
Set<Modifier> mods = doc.getModifiers();
if (mods.contains(Modifier.PRIVATE)) {
return PRIVATE;
} else if (mods.contains(Modifier.PROTECTED)) {
return PROTECTED;
} else if (mods.contains(Modifier.PUBLIC)) {
return PUBLIC;
} else {
return PACKAGE;
}
}
}

View File

@ -1,369 +0,0 @@
/*
* Create a graphviz graph based on the classes in the specified java
* source files.
*
* (C) Copyright 2002-2005 Diomidis Spinellis
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
*/
package org.umlgraph.doclet;
import com.sun.javadoc.AnnotatedType;
import com.sun.javadoc.AnnotationDesc;
import com.sun.javadoc.AnnotationTypeDoc;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.ConstructorDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.ParamTag;
import com.sun.javadoc.ParameterizedType;
import com.sun.javadoc.SeeTag;
import com.sun.javadoc.SourcePosition;
import com.sun.javadoc.Tag;
import com.sun.javadoc.Type;
import com.sun.javadoc.TypeVariable;
import com.sun.javadoc.WildcardType;
/**
* A ClassDoc wrapper that caches answer to the most common requests performed
* by UMLGraph, considerably improving the overall UMLDoc performance (ClassDoc
* computes most of the results for more fine grained information at each call).
* <p>
* Unfortunately this has a side effect, since it breaks the equals() call between
* plain ClassDoc instances and WrappedClassDoc ones, so use it with due care.
* <p>
* In particular, don't provide WrappedClassDoc instances to the standard doclet.
* @author wolf
*
*/
public class WrappedClassDoc implements ClassDoc {
ClassDoc wrapped;
String toString;
String name;
Tag[] tags;
public WrappedClassDoc(ClassDoc wrapped) {
this.wrapped = wrapped;
}
public AnnotationDesc[] annotations() {
return wrapped.annotations();
}
public AnnotationTypeDoc asAnnotationTypeDoc() {
return wrapped.asAnnotationTypeDoc();
}
public ClassDoc asClassDoc() {
return wrapped.asClassDoc();
}
public ParameterizedType asParameterizedType() {
return wrapped.asParameterizedType();
}
public TypeVariable asTypeVariable() {
return wrapped.asTypeVariable();
}
public WildcardType asWildcardType() {
return wrapped.asWildcardType();
}
public String commentText() {
return wrapped.commentText();
}
public int compareTo(Object arg0) {
if (arg0 instanceof WrappedClassDoc) {
WrappedClassDoc other = (WrappedClassDoc) arg0;
return wrapped.compareTo(other.wrapped);
}
return wrapped.compareTo(arg0);
}
public ConstructorDoc[] constructors() {
return wrapped.constructors();
}
public ConstructorDoc[] constructors(boolean arg0) {
return wrapped.constructors(arg0);
}
public ClassDoc containingClass() {
return wrapped.containingClass();
}
public PackageDoc containingPackage() {
return wrapped.containingPackage();
}
public boolean definesSerializableFields() {
return wrapped.definesSerializableFields();
}
public String dimension() {
return wrapped.dimension();
}
public FieldDoc[] enumConstants() {
return wrapped.enumConstants();
}
public FieldDoc[] fields() {
return wrapped.fields();
}
public FieldDoc[] fields(boolean arg0) {
return wrapped.fields(arg0);
}
public ClassDoc findClass(String arg0) {
return wrapped.findClass(arg0);
}
public Tag[] firstSentenceTags() {
return wrapped.firstSentenceTags();
}
public String getRawCommentText() {
return wrapped.getRawCommentText();
}
/** @deprecated */
public @Deprecated ClassDoc[] importedClasses() {
return wrapped.importedClasses();
}
/** @deprecated */
public @Deprecated PackageDoc[] importedPackages() {
return wrapped.importedPackages();
}
public Tag[] inlineTags() {
return wrapped.inlineTags();
}
public ClassDoc[] innerClasses() {
return wrapped.innerClasses();
}
public ClassDoc[] innerClasses(boolean arg0) {
return wrapped.innerClasses(arg0);
}
public ClassDoc[] interfaces() {
return wrapped.interfaces();
}
public Type[] interfaceTypes() {
return wrapped.interfaceTypes();
}
public boolean isAbstract() {
return wrapped.isAbstract();
}
public boolean isAnnotationType() {
return wrapped.isAnnotationType();
}
public boolean isAnnotationTypeElement() {
return wrapped.isAnnotationTypeElement();
}
public boolean isClass() {
return wrapped.isClass();
}
public boolean isConstructor() {
return wrapped.isConstructor();
}
public boolean isEnum() {
return wrapped.isEnum();
}
public boolean isEnumConstant() {
return wrapped.isEnumConstant();
}
public boolean isError() {
return wrapped.isError();
}
public boolean isException() {
return wrapped.isException();
}
public boolean isExternalizable() {
return wrapped.isExternalizable();
}
public boolean isField() {
return wrapped.isField();
}
public boolean isFinal() {
return wrapped.isFinal();
}
public boolean isIncluded() {
return wrapped.isIncluded();
}
public boolean isInterface() {
return wrapped.isInterface();
}
public boolean isMethod() {
return wrapped.isMethod();
}
public boolean isOrdinaryClass() {
return wrapped.isOrdinaryClass();
}
public boolean isPackagePrivate() {
return wrapped.isPackagePrivate();
}
public boolean isPrimitive() {
return wrapped.isPrimitive();
}
public boolean isPrivate() {
return wrapped.isPrivate();
}
public boolean isProtected() {
return wrapped.isProtected();
}
public boolean isPublic() {
return wrapped.isPublic();
}
public boolean isSerializable() {
return wrapped.isSerializable();
}
public boolean isStatic() {
return wrapped.isStatic();
}
public MethodDoc[] methods() {
return wrapped.methods();
}
public MethodDoc[] methods(boolean arg0) {
return wrapped.methods(arg0);
}
public String modifiers() {
return wrapped.modifiers();
}
public int modifierSpecifier() {
return wrapped.modifierSpecifier();
}
public String name() {
if (name == null)
name = wrapped.name();
return name;
}
public SourcePosition position() {
return wrapped.position();
}
public String qualifiedName() {
return wrapped.qualifiedName();
}
public String qualifiedTypeName() {
return wrapped.qualifiedTypeName();
}
public SeeTag[] seeTags() {
return wrapped.seeTags();
}
public FieldDoc[] serializableFields() {
return wrapped.serializableFields();
}
public MethodDoc[] serializationMethods() {
return wrapped.serializationMethods();
}
public void setRawCommentText(String arg0) {
wrapped.setRawCommentText(arg0);
}
public String simpleTypeName() {
return wrapped.simpleTypeName();
}
public boolean subclassOf(ClassDoc arg0) {
return wrapped.subclassOf(arg0);
}
public ClassDoc superclass() {
return wrapped.superclass();
}
public Type superclassType() {
return wrapped.superclassType();
}
public Tag[] tags() {
if (tags == null)
tags = wrapped.tags();
return tags;
}
public Tag[] tags(String arg0) {
return wrapped.tags(arg0);
}
public String toString() {
if (toString == null) {
toString = wrapped.toString();
}
return toString;
}
public String typeName() {
return wrapped.typeName();
}
public TypeVariable[] typeParameters() {
return wrapped.typeParameters();
}
public ParamTag[] typeParamTags() {
return wrapped.typeParamTags();
}
public AnnotatedType asAnnotatedType() {
return wrapped.asAnnotatedType();
}
public Type getElementType() {
return wrapped.getElementType();
}
}

View File

@ -1,191 +0,0 @@
/*
* Create a graphviz graph based on the classes in the specified java
* source files.
*
* (C) Copyright 2002-2005 Diomidis Spinellis
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
*/
package org.umlgraph.doclet;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.SeeTag;
import com.sun.javadoc.SourcePosition;
import com.sun.javadoc.Tag;
/**
* RootDoc wrapper that provides WrappedClassDoc instances instead of plain ClassDoc in order
* to optimize the overall performance of UMLDoc.
* @author wolf
*/
public class WrappedRootDoc implements RootDoc {
RootDoc wrapped;
WrappedClassDoc[] wrappedClassDocs;
public WrappedRootDoc(RootDoc wrapped) {
this.wrapped = wrapped;
ClassDoc[] classes = wrapped.classes();
wrappedClassDocs = new WrappedClassDoc[classes.length];
for (int i = 0; i < classes.length; i++) {
wrappedClassDocs[i] = new WrappedClassDoc(classes[i]);
}
}
public ClassDoc[] classes() {
return wrappedClassDocs;
}
public ClassDoc classNamed(String arg0) {
return wrapped.classNamed(arg0);
}
public String commentText() {
return wrapped.commentText();
}
public int compareTo(Object arg0) {
return wrapped.compareTo(arg0);
}
public Tag[] firstSentenceTags() {
return wrapped.firstSentenceTags();
}
public String getRawCommentText() {
return wrapped.getRawCommentText();
}
public Tag[] inlineTags() {
return wrapped.inlineTags();
}
public boolean isAnnotationType() {
return wrapped.isAnnotationType();
}
public boolean isAnnotationTypeElement() {
return wrapped.isAnnotationTypeElement();
}
public boolean isClass() {
return wrapped.isClass();
}
public boolean isConstructor() {
return wrapped.isConstructor();
}
public boolean isEnum() {
return wrapped.isEnum();
}
public boolean isEnumConstant() {
return wrapped.isEnumConstant();
}
public boolean isError() {
return wrapped.isError();
}
public boolean isException() {
return wrapped.isException();
}
public boolean isField() {
return wrapped.isField();
}
public boolean isIncluded() {
return wrapped.isIncluded();
}
public boolean isInterface() {
return wrapped.isInterface();
}
public boolean isMethod() {
return wrapped.isMethod();
}
public boolean isOrdinaryClass() {
return wrapped.isOrdinaryClass();
}
public String name() {
return wrapped.name();
}
public String[][] options() {
return wrapped.options();
}
public PackageDoc packageNamed(String arg0) {
return wrapped.packageNamed(arg0);
}
public SourcePosition position() {
return wrapped.position();
}
public void printError(SourcePosition arg0, String arg1) {
wrapped.printError(arg0, arg1);
}
public void printError(String arg0) {
wrapped.printError(arg0);
}
public void printNotice(SourcePosition arg0, String arg1) {
wrapped.printNotice(arg0, arg1);
}
public void printNotice(String arg0) {
wrapped.printNotice(arg0);
}
public void printWarning(SourcePosition arg0, String arg1) {
wrapped.printWarning(arg0, arg1);
}
public void printWarning(String arg0) {
wrapped.printWarning(arg0);
}
public SeeTag[] seeTags() {
return wrapped.seeTags();
}
public void setRawCommentText(String arg0) {
wrapped.setRawCommentText(arg0);
}
public ClassDoc[] specifiedClasses() {
return wrapped.specifiedClasses();
}
public PackageDoc[] specifiedPackages() {
return wrapped.specifiedPackages();
}
public Tag[] tags() {
return wrapped.tags();
}
public Tag[] tags(String arg0) {
return wrapped.tags(arg0);
}
}

View File

@ -0,0 +1,168 @@
package org.umlgraph.doclet.util;
import static com.sun.source.doctree.DocTree.Kind.CODE;
import java.util.List;
import com.sun.source.doctree.AttributeTree;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.EndElementTree;
import com.sun.source.doctree.EntityTree;
import com.sun.source.doctree.LinkTree;
import com.sun.source.doctree.LiteralTree;
import com.sun.source.doctree.ReferenceTree;
import com.sun.source.doctree.SeeTree;
import com.sun.source.doctree.SerialTree;
import com.sun.source.doctree.StartElementTree;
import com.sun.source.doctree.TextTree;
import com.sun.source.doctree.UnknownBlockTagTree;
import com.sun.source.doctree.ValueTree;
import com.sun.source.doctree.AttributeTree.ValueKind;
import com.sun.source.util.SimpleDocTreeVisitor;
public class CommentHelper {
public static final String SPACER = " ";
public static String getText(List<? extends DocTree> list) {
StringBuilder sb = new StringBuilder();
for (DocTree dt : list) {
sb.append(getText0(dt));
}
return sb.toString();
}
public static String getText(DocTree dt) {
return getText0(dt).toString();
}
private static StringBuilder getText0(DocTree dt) {
final StringBuilder sb = new StringBuilder();
new SimpleDocTreeVisitor<Void, Void>() {
@Override
public Void visitAttribute(AttributeTree node, Void p) {
sb.append(SPACER).append(node.getName());
if (node.getValueKind() == ValueKind.EMPTY) {
return null;
}
sb.append("=");
String quote;
switch (node.getValueKind()) {
case DOUBLE:
quote = "\"";
break;
case SINGLE:
quote = "\'";
break;
default:
quote = "";
break;
}
sb.append(quote);
node.getValue().stream().forEach((dt) -> {
dt.accept(this, null);
});
sb.append(quote);
return null;
}
@Override
public Void visitEndElement(EndElementTree node, Void p) {
sb.append("</")
.append(node.getName())
.append(">");
return null;
}
@Override
public Void visitEntity(EntityTree node, Void p) {
sb.append(node.toString());
return null;
}
@Override
public Void visitLink(LinkTree node, Void p) {
if (node.getReference() == null) {
return null;
}
node.getReference().accept(this, null);
node.getLabel().stream().forEach((dt) -> {
dt.accept(this, null);
});
return null;
}
@Override
public Void visitLiteral(LiteralTree node, Void p) {
if (node.getKind() == CODE) {
sb.append("<").append(node.getKind().tagName).append(">");
}
sb.append(node.getBody().toString());
if (node.getKind() == CODE) {
sb.append("</").append(node.getKind().tagName).append(">");
}
return null;
}
@Override
public Void visitReference(ReferenceTree node, Void p) {
sb.append(node.getSignature());
return null;
}
@Override
public Void visitSee(SeeTree node, Void p) {
node.getReference().stream().forEach((dt) -> {
dt.accept(this, null);
});
return null;
}
@Override
public Void visitSerial(SerialTree node, Void p) {
node.getDescription().stream().forEach((dt) -> {
dt.accept(this, null);
});
return null;
}
@Override
public Void visitStartElement(StartElementTree node, Void p) {
sb.append("<");
sb.append(node.getName());
node.getAttributes().stream().forEach((dt) -> {
dt.accept(this, null);
});
sb.append((node.isSelfClosing() ? "/>" : ">"));
return null;
}
@Override
public Void visitText(TextTree node, Void p) {
sb.append(node.getBody());
return null;
}
@Override
public Void visitUnknownBlockTag(UnknownBlockTagTree node, Void p) {
node.getContent().stream().forEach((dt) -> {
dt.accept(this, null);
});
return null;
}
@Override
public Void visitValue(ValueTree node, Void p) {
return node.getReference().accept(this, null);
}
@Override
protected Void defaultAction(DocTree node, Void p) {
sb.append(node.toString());
return null;
}
}.visit(dt, null);
return sb;
}
}

View File

@ -0,0 +1,193 @@
package org.umlgraph.doclet.util;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import jdk.javadoc.doclet.DocletEnvironment;
public class ElementUtil {
public static boolean isPrimitive(TypeMirror type) {
if (type.getKind().isPrimitive()) {
return true;
}
if (type.getKind() == TypeKind.ARRAY) {
return isPrimitive(((ArrayType) type).getComponentType());
}
return false;
}
public static boolean isType(TypeMirror type, TypeKind kind) {
if (type.getKind() == kind) {
return true;
}
if (type.getKind() == TypeKind.ARRAY) {
return isType(((ArrayType) type).getComponentType(), kind);
}
return false;
}
public static CharSequence getSimpleName(Types types, TypeMirror t) {
if (t instanceof ArrayType) {
return getSimpleName(types, ((ArrayType) t).getComponentType()) + "[]";
}
if (t.getKind().isPrimitive()) {
return t.getKind().name().toLowerCase();
}
Element element = types.asElement(t);
if (element != null) {
return element.getSimpleName();
}
return "";
}
public static CharSequence getQualifiedName(Types types, TypeMirror t) {
if (t instanceof ArrayType) {
return getQualifiedName(types, ((ArrayType) t).getComponentType()) + "[]";
}
if (t.getKind().isPrimitive()) {
return t.getKind().name().toLowerCase();
}
Element element = types.asElement(t);
if (element instanceof TypeElement) {
return ((TypeElement) element).getQualifiedName();
}
if (element instanceof TypeVariable) {
return element.getSimpleName();
}
return "";
}
public static TypeElement containingTypeElement(Element c) {
if (c instanceof VariableElement) {
Element enclosing = c.getEnclosingElement();
return enclosing instanceof TypeElement ? (TypeElement) enclosing : null;
} else if (c instanceof ExecutableElement) {
Element enclosing = c.getEnclosingElement();
return enclosing instanceof TypeElement ? (TypeElement) enclosing : null;
}
if (c == null) {
System.err.println("containingElement will return null for null element");
return null;
}
System.err.println("containingElement will return null for kind " + c.getKind() + " class " + c.getClass() + " name " + c.getSimpleName());
return null;
}
public static TypeElement getTypeElement(TypeMirror clazz) {
if (clazz == null || clazz.getKind() == TypeKind.NONE) {
return null;
}
if (clazz instanceof ArrayType) {
TypeMirror componentType = ((ArrayType) clazz).getComponentType();
return getTypeElement(componentType);
}
if (!(clazz instanceof DeclaredType)) {
System.err.println("getTypeElement will return null for type class : " + clazz + " instanceof " + clazz.getClass() + " and kind " + clazz.getKind());
return null;
}
Element scd = ((DeclaredType) clazz).asElement();
if (!(scd instanceof TypeElement)) {
System.err.println("getTypeElement will return null for element class : " + scd == null ? "null" : scd.getClass());
return null;
}
return (TypeElement) scd;
}
public static TypeMirror getSuperclassType(DeclaredType pt) {
return pt.asElement() instanceof TypeElement ? ((TypeElement) pt.asElement()).getSuperclass() : null;
}
public static TypeElement getSuperclass(TypeElement element) {
return getTypeElement(element.getSuperclass());
}
public static List<? extends TypeMirror> getInterfacesTypes(Element element) {
if (element instanceof TypeElement) {
return ((TypeElement) element).getInterfaces();
}
return Collections.emptyList();
}
public static List<TypeElement> getInterfaces(TypeElement element) {
List<? extends TypeMirror> interfaces = getInterfacesTypes(element);
return interfaces.stream().map(i -> getTypeElement(i)).filter(i -> i != null).collect(Collectors.toList());
}
public static ModuleElement getModuleOf(DocletEnvironment root, Element element) {
return getModuleOf(root.getElementUtils(), element);
}
public static ModuleElement getModuleOf(Elements elements, Element element) {
if (element == null) {
return null;
}
if (element instanceof ModuleElement) {
return (ModuleElement) element;
}
return elements.getModuleOf(element);
}
public static PackageElement getPackageOf(DocletEnvironment root, Element element) {
return getPackageOf(root.getElementUtils(), element);
}
public static PackageElement getPackageOf(Elements elements, Element element) {
if (element == null) {
return null;
}
if (element instanceof PackageElement) {
return (PackageElement) element;
}
return elements.getPackageOf(element);
}
public static List<VariableElement> getFields(TypeElement element) {
List<? extends Element> enclosed = element.getEnclosedElements();
return ElementFilter.fieldsIn(enclosed).stream().filter(v -> v.getKind() == ElementKind.FIELD).collect(Collectors.toList());
}
public static List<VariableElement> getEnumConstants(TypeElement element) {
List<? extends Element> enclosed = element.getEnclosedElements();
return ElementFilter.fieldsIn(enclosed).stream().filter(v -> v.getKind() == ElementKind.ENUM_CONSTANT).collect(Collectors.toList());
}
public static List<ExecutableElement> getMethods(TypeElement element) {
List<? extends Element> enclosed = element.getEnclosedElements();
return ElementFilter.methodsIn(enclosed);
}
public static List<ExecutableElement> getConstructors(TypeElement element) {
List<? extends Element> enclosed = element.getEnclosedElements();
return ElementFilter.constructorsIn(enclosed);
}
public static String dimensions(TypeMirror type) {
StringBuilder sb = new StringBuilder();
// First append root component type
TypeMirror t = type;
while (t.getKind() == TypeKind.ARRAY) {
sb.append("[]");
t = ((ArrayType) t).getComponentType();
}
return sb.toString();
}
}

View File

@ -0,0 +1,50 @@
package org.umlgraph.doclet.util;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.Element;
import org.umlgraph.doclet.TagScanner;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.util.DocTrees;
import jdk.javadoc.doclet.DocletEnvironment;
public class TagUtil {
public static Map<String, List<String>> getTags(DocletEnvironment root, Element c) {
return getTags(root.getDocTrees(), c);
}
public static Map<String, List<String>> getTags(DocTrees docTrees, Element c) {
DocCommentTree tree = docTrees.getDocCommentTree(c);
Map<String, List<String>> tagsByName = new HashMap<>();
new TagScanner(tagsByName).visitDocComment(tree, null);
return tagsByName;
}
public static String getComment(DocletEnvironment root, Element c) {
return getComment(root.getDocTrees(), c);
}
public static String getComment(DocTrees docTrees, Element c) {
List<String> comments = getTag(docTrees, c, "comment");
if (comments == null || comments.isEmpty()) {
return "";
}
return comments.get(0);
}
public static List<String> getTag(DocletEnvironment root, Element c, String tagName) {
return getTag(root.getDocTrees(), c, tagName);
}
public static List<String> getTag(DocTrees docTrees, Element c, String tagName) {
List<String> tags = getTags(docTrees, c).get(tagName);
return tags == null ? Collections.emptyList() : tags;
}
}

View File

@ -26,6 +26,14 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.tools.DocumentationTool;
import javax.tools.ToolProvider;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.umlgraph.doclet.UmlGraph;
/**
* UmlGraph regression tests
* @author wolf
@ -41,18 +49,18 @@ public class BasicTest {
static PrintWriter pw = new PrintWriter(System.out);
public static void main(String[] args) throws IOException {
@Test
@Ignore
public void test() throws IOException {
List<String> differences = new ArrayList<String>();
File outFolder = new File(testDestFolder);
if (!outFolder.exists())
if (!outFolder.exists()) {
outFolder.mkdirs();
}
TestUtils.cleanFolder(outFolder, true);
// don't use windows specific fonts
System.setProperty("os.name", "generic");
// run tests
performBasicTests(differences);
performViewTests(differences, outFolder);
@ -67,13 +75,14 @@ public class BasicTest {
pw.println();
pw.println();
pw.flush();
Assert.assertEquals("Some differences found " + differences.size(), 0, differences.size());
}
private static void performViewTests(List<String> differences, File outFolder)
throws IOException {
String[] options = new String[] { "-docletpath", "build", "-private", "-d",
outFolder.getAbsolutePath(), "-sourcepath", "testdata/java", "-compact",
"-subpackages", "gr.spinellis", "-views" };
String[] options = new String[] { "--docletpath=build", "-private",
"--d=\"" + outFolder.getAbsolutePath() + "\"", "--sourcepath=\"testdata/java\"", "-compact",
"--subpackages=\"gr.spinellis\"", "-views" };
runDoclet(options);
List<String> viewFiles = new ArrayList<String>();
@ -120,8 +129,8 @@ public class BasicTest {
dotFile.delete();
File refFile = new File(testRefFolder, outFileName);
String javaPath = new File(testSourceFolder, javaFiles[i]).getAbsolutePath();
String[] options = new String[] { "-docletpath", "build", "-hide", "Hidden",
"-compact", "-private", "-d", testDestFolder, "-output", outFileName, javaPath };
String[] options = new String[] { "--docletpath=build", "--hide=\"Hidden\"",
"-compact", "-private", "--d=\"" + testDestFolder + "\"", "--output=\"" + outFileName + "\"", javaPath };
runDoclet(options);
compare(differences, dotFile, refFile);
@ -130,8 +139,9 @@ public class BasicTest {
}
private static void runDoclet(String[] options) {
com.sun.tools.javadoc.Main.execute("UMLGraph test", pw, pw, pw,
"org.umlgraph.doclet.UmlGraph", options);
DocumentationTool systemDocumentationTool = ToolProvider.getSystemDocumentationTool();
DocumentationTool.DocumentationTask task = systemDocumentationTool.getTask(pw, null, null, UmlGraph.class, Arrays.asList(options), null);
task.call();
}
private static void compare(List<String> differences, File dotFile, File refFile)

View File

@ -166,16 +166,15 @@ public class DotDiff {
int closedBracketIdx = line.lastIndexOf(']');
int arrowIdx = line.indexOf("->");
if (openBrackedIdx < 0 && closedBracketIdx < 0 || line.startsWith("edge")
|| line.startsWith("node"))
|| line.startsWith("node") || line.startsWith("graph"))
extraLines.add(line);
else if (arrowIdx > 0 && arrowIdx < openBrackedIdx) { // that's an arc
arcLines.add(line);
} else { // that's a node
String attributes = line.substring(openBrackedIdx + 1, closedBracketIdx);
Map<String, String> attMap = parseAttributes(attributes);
String name = line.substring(0, openBrackedIdx - 1).trim();
String label = attMap.get("label");
DotNode node = new DotNode(name, label, attMap, line);
String name = trim(line.substring(0, openBrackedIdx - 1));
DotNode node = new DotNode(name, attMap.get("label"), attMap, line);
nodes.put(name, node);
nodeList.add(node);
}
@ -185,19 +184,21 @@ public class DotDiff {
int closedBracketIdx = line.lastIndexOf(']');
String attributes = line.substring(openBrackedIdx + 1, closedBracketIdx);
String[] names = line.substring(0, openBrackedIdx).split("->");
DotNode from = nodes.get(names[0].trim());
DotNode to = nodes.get(names[1].trim());
if (from == null) {
from = new DotNode(names[0], "", new HashMap<String, String>(), "");
}
if (to == null) {
to = new DotNode(names[1], "", new HashMap<String, String>(), "");
}
DotNode from = nodes.get(names[0] = trim(names[0]));
DotNode to = nodes.get(names[1] = trim(names[1]));
from = from != null ? from : new DotNode(names[0], "", new HashMap<String, String>(), "");
to = to != null? to : new DotNode(names[1], "", new HashMap<String, String>(), "");
arcs.add(new DotArc(from, to, parseAttributes(attributes), line));
}
return extraLines;
}
// Trim space AND port.
private String trim(String name) {
name = name.trim();
return name.endsWith(":p") ? name.substring(0, name.length() - 2) : name;
}
private Map<String, String> parseAttributes(String attributes) throws IOException {
Map<String, String> map = new HashMap<String, String>();

View File

@ -21,6 +21,12 @@ package org.umlgraph.test;
import java.io.File;
import java.io.PrintWriter;
import java.util.Arrays;
import javax.tools.DocumentationTool;
import javax.tools.ToolProvider;
import org.umlgraph.doclet.UmlGraphDoc;
public class RunDoc {
@ -34,14 +40,15 @@ public class RunDoc {
File outFolder = new File(docFolder);
if (!outFolder.exists())
outFolder.mkdirs();
String[] options = new String[] { "-docletpath", "build", "-private", "-d", docFolder,
String[] options = new String[] { "-docletpath", "build", "-private", "--d", docFolder,
"-sourcepath", sourcesFolder, "-subpackages", "gr.spinellis" };
runDoclet(options);
}
private static void runDoclet(String[] options) {
com.sun.tools.javadoc.Main.execute("UMLGraph test", pw, pw, pw,
"org.umlgraph.doclet.UmlGraphDoc", options);
DocumentationTool systemDocumentationTool = ToolProvider.getSystemDocumentationTool();
DocumentationTool.DocumentationTask task = systemDocumentationTool.getTask(pw, null, null, UmlGraphDoc.class, Arrays.asList(options), null);
task.call();
}
}

View File

@ -21,6 +21,12 @@ package org.umlgraph.test;
import java.io.File;
import java.io.PrintWriter;
import java.util.Arrays;
import javax.tools.DocumentationTool;
import javax.tools.ToolProvider;
import org.umlgraph.doclet.UmlGraph;
public class RunOne {
@ -53,8 +59,8 @@ public class RunOne {
}
private static void runDoclet(String[] options) {
com.sun.tools.javadoc.Main.execute("UMLGraph test", pw, pw, pw, "org.umlgraph.doclet.UmlGraph", options);
DocumentationTool systemDocumentationTool = ToolProvider.getSystemDocumentationTool();
DocumentationTool.DocumentationTask task = systemDocumentationTool.getTask(pw, null, null, UmlGraph.class, Arrays.asList(options), null);
task.call();
}
}

View File

@ -25,6 +25,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.tools.DocumentationTool;
import javax.tools.ToolProvider;
import org.junit.Ignore;
import org.junit.Test;
import org.umlgraph.doclet.UmlGraphDoc;
/**
* UmlGraphDoc doclet regression tests
* @author wolf
@ -41,7 +48,9 @@ public class UmlDocTest {
static PrintWriter pw = new PrintWriter(System.out);
public static void main(String[] args) throws IOException {
@Test
@Ignore
public void test() throws IOException {
List<String> differences = new ArrayList<String>();
File outFolder = new File(testDestFolder);
@ -50,9 +59,6 @@ public class UmlDocTest {
TestUtils.cleanFolder(outFolder, true);
// don't use windows specific fonts
System.setProperty("os.name", "generic");
// run tests
runTest(differences);
if (differences.size() > 0) {
@ -60,6 +66,7 @@ public class UmlDocTest {
for (String className : differences) {
pw.println(className);
}
System.exit(1);
} else {
pw.println("GOOD, all files are structurally equal");
}
@ -70,10 +77,11 @@ public class UmlDocTest {
private static void runTest(List<String> differences) throws IOException {
File outFolder = new File(testDestFolder);
String[] options = new String[] { "-docletpath", "build", "-private", "-d",
outFolder.getAbsolutePath(), "-sourcepath", testSourceFolder, "-compact",
File srcFolder = new File(testSourceFolder);
String[] options = new String[] { "-private", "--d=\"" + outFolder.getAbsolutePath() + "\"",
"--source-path=\"" + srcFolder.getAbsolutePath() + "\"", "-compact",
"-subpackages", "gr.spinellis", "-inferrel", "-inferdep", "-qualify",
"-postfixpackage", "-collpackages", "java.util.*" };
"-postfixpackage", "--collpackages=\"java.util.*\"" };
runDoclet(options);
compareDocletOutputs(differences, new File(testRefFolder), new File(testDestFolder));
@ -121,8 +129,9 @@ public class UmlDocTest {
differences.add(out.getName() + " is different from the reference");
} else {
if (!TestUtils.textFilesEquals(pw, ref, out))
if (!TestUtils.textFilesEquals(pw, ref, out)) {
differences.add(out.getName() + " is different from the reference");
}
}
i++;
j++;
@ -148,12 +157,14 @@ public class UmlDocTest {
* @param options
*/
private static void runDoclet(String[] options) {
pw.print("Run javadoc -doclet " + doclet);
for (String o : options)
pw.print(o + " ");
pw.println();
com.sun.tools.javadoc.Main.execute("UMLDoc test", pw, pw, pw,
doclet, options);
pw.print("Run javadoc -doclet " + doclet);
for (String o : options) {
pw.print(" " + o);
}
pw.println();
DocumentationTool systemDocumentationTool = ToolProvider.getSystemDocumentationTool();
DocumentationTool.DocumentationTask task = systemDocumentationTool.getTask(pw, null, null, UmlGraphDoc.class, Arrays.asList(options), null);
task.call();
}
}

View File

@ -1,2 +1 @@
*.dot
*.png

View File

@ -5,21 +5,22 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// test.AbstractNode
c1 [label=<<table title="test.AbstractNode" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="Helvetica-Oblique"> AbstractNode </font></td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> abstractMethod() </font></td></tr><tr><td align="left" balign="left"> concreteMethod() </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// test.InnerNode
c2 [label=<<table title="test.InnerNode" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InnerNode </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// test.Leaf
c3 [label=<<table title="test.Leaf" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Leaf </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//test.InnerNode extends test.AbstractNode
c1:p -> c2:p [dir=back,arrowtail=empty];
// test.InnerNode COMPOSED test.AbstractNode
c2:p -> c1:p [taillabel="1", label="has", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
//test.Leaf extends test.AbstractNode
c1:p -> c3:p [dir=back,arrowtail=empty];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// test.AbstractNode
c1 [label=<<table title="test.AbstractNode" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><i> AbstractNode </i></td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"><i> abstractMethod() </i></td></tr><tr><td align="left" balign="left"> concreteMethod() </td></tr></table></td></tr></table>>];
// test.InnerNode
c2 [label=<<table title="test.InnerNode" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InnerNode </td></tr></table></td></tr></table>>];
// test.Leaf
c3 [label=<<table title="test.Leaf" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Leaf </td></tr></table></td></tr></table>>];
// test.InnerNode extends test.AbstractNode
c1 -> c2 [arrowtail=empty,dir=back,weight=10];
// test.InnerNode composed test.AbstractNode
c2 -> c1 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1", label="has", headlabel="*"];
// test.Leaf extends test.AbstractNode
c1 -> c3 [arrowtail=empty,dir=back,weight=10];
}

View File

@ -1,49 +1,50 @@
#!/usr/local/bin/dot
#
# Class diagram
# Generated by UMLGraph version R5_7_0-10-g786d98 (http://www.umlgraph.org/)
# Generated by UMLGraph version R5_7_2-10-g442559 (http://www.umlgraph.org/)
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// A
c66 [label=<<table title="A" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> A </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> first : B </td></tr><tr><td align="left" balign="left"> second : B </td></tr><tr><td align="left" balign="left"> third : C </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// B
c67 [label=<<table title="B" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> B </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> doSomething(b : B, c : C) : A </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// C
c68 [label=<<table title="C" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> C </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> collectionOfA : List&lt;A&gt; </td></tr><tr><td align="left" balign="left"> collectionOfB : ArrayList&lt;B&gt; </td></tr><tr><td align="left" balign="left"> mapOfD : Map&lt;String, D&gt; </td></tr><tr><td align="left" balign="left"> childs : C[] </td></tr><tr><td align="left" balign="left"> anOpaqueList : List&lt;&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// MyFunnyList<T, V>
c69 [label=<<table title="MyFunnyList" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> MyFunnyList&lt;T, V&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> myField : V </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// MyList
c70 [label=<<table title="MyList" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> MyList </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// D
c71 [label=<<table title="D" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> D </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> anotherListOfA : MyList </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//MyFunnyList<T, V> extends java.util.ArrayList<T>
c72:p -> c69:p [dir=back,arrowtail=empty];
//MyList extends MyFunnyList<A, B>
c69:p -> c70:p [dir=back,arrowtail=empty];
// A HAS B
c66:p -> c67:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=ediamond, dir=both];
// A HAS C
c66:p -> c68:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=ediamond, dir=both];
// C NAVASSOC B
c68:p -> c67:p [taillabel="", label="", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// C NAVASSOC D
c68:p -> c71:p [taillabel="", label="", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// C NAVASSOC C
c68:p -> c68:p [taillabel="", label="", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// C NAVASSOC java.util.List<E>
c68:p -> c73:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// D NAVASSOC MyList
c71:p -> c70:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// B DEPEND A
c67:p -> c66:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open, style=dashed];
// java.util.List<E>
c73 [label=<<table title="java.util.List" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> List&lt;E&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> size() : int </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> isEmpty() : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> contains(arg0 : Object) : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> iterator() : Iterator&lt;E&gt; </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> toArray() : Object[] </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> toArray(arg0 : T[]) : T[] </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> add(arg0 : E) : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> remove(arg0 : Object) : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> containsAll(arg0 : Collection&lt;?&gt;) : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> addAll(arg0 : Collection&lt;?&gt;) : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> addAll(arg0 : int, arg1 : Collection&lt;?&gt;) : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> removeAll(arg0 : Collection&lt;?&gt;) : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> retainAll(arg0 : Collection&lt;?&gt;) : boolean </font></td></tr><tr><td align="left" balign="left"> replaceAll(arg0 : UnaryOperator&lt;E&gt;) </td></tr><tr><td align="left" balign="left"> sort(arg0 : Comparator&lt;?&gt;) </td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> clear() </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> equals(arg0 : Object) : boolean </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> hashCode() : int </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> get(arg0 : int) : E </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> set(arg0 : int, arg1 : E) : E </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> add(arg0 : int, arg1 : E) </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> remove(arg0 : int) : E </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> indexOf(arg0 : Object) : int </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> lastIndexOf(arg0 : Object) : int </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> listIterator() : ListIterator&lt;E&gt; </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> listIterator(arg0 : int) : ListIterator&lt;E&gt; </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> subList(arg0 : int, arg1 : int) : List&lt;E&gt; </font></td></tr><tr><td align="left" balign="left"> spliterator() : Spliterator&lt;E&gt; </td></tr></table></td></tr></table>>, URL="http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// java.util.ArrayList<E>
c72 [label=<<table title="java.util.ArrayList" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ArrayList&lt;E&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> serialVersionUID : long </td></tr><tr><td align="left" balign="left"> DEFAULT_CAPACITY : int </td></tr><tr><td align="left" balign="left"> EMPTY_ELEMENTDATA : Object[] </td></tr><tr><td align="left" balign="left"> DEFAULTCAPACITY_EMPTY_ELEMENTDATA : Object[] </td></tr><tr><td align="left" balign="left"> elementData : Object[] </td></tr><tr><td align="left" balign="left"> size : int </td></tr><tr><td align="left" balign="left"> MAX_ARRAY_SIZE : int </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> trimToSize() </td></tr><tr><td align="left" balign="left"> ensureCapacity(arg0 : int) </td></tr><tr><td align="left" balign="left"> ensureCapacityInternal(arg0 : int) </td></tr><tr><td align="left" balign="left"> ensureExplicitCapacity(arg0 : int) </td></tr><tr><td align="left" balign="left"> grow(arg0 : int) </td></tr><tr><td align="left" balign="left"> hugeCapacity(arg0 : int) : int </td></tr><tr><td align="left" balign="left"> size() : int </td></tr><tr><td align="left" balign="left"> isEmpty() : boolean </td></tr><tr><td align="left" balign="left"> contains(arg0 : Object) : boolean </td></tr><tr><td align="left" balign="left"> indexOf(arg0 : Object) : int </td></tr><tr><td align="left" balign="left"> lastIndexOf(arg0 : Object) : int </td></tr><tr><td align="left" balign="left"> clone() : Object </td></tr><tr><td align="left" balign="left"> toArray() : Object[] </td></tr><tr><td align="left" balign="left"> toArray(arg0 : T[]) : T[] </td></tr><tr><td align="left" balign="left"> elementData(arg0 : int) : E </td></tr><tr><td align="left" balign="left"> get(arg0 : int) : E </td></tr><tr><td align="left" balign="left"> set(arg0 : int, arg1 : E) : E </td></tr><tr><td align="left" balign="left"> add(arg0 : E) : boolean </td></tr><tr><td align="left" balign="left"> add(arg0 : int, arg1 : E) </td></tr><tr><td align="left" balign="left"> remove(arg0 : int) : E </td></tr><tr><td align="left" balign="left"> remove(arg0 : Object) : boolean </td></tr><tr><td align="left" balign="left"> fastRemove(arg0 : int) </td></tr><tr><td align="left" balign="left"> clear() </td></tr><tr><td align="left" balign="left"> addAll(arg0 : Collection&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> addAll(arg0 : int, arg1 : Collection&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> removeRange(arg0 : int, arg1 : int) </td></tr><tr><td align="left" balign="left"> rangeCheck(arg0 : int) </td></tr><tr><td align="left" balign="left"> rangeCheckForAdd(arg0 : int) </td></tr><tr><td align="left" balign="left"> outOfBoundsMsg(arg0 : int) : String </td></tr><tr><td align="left" balign="left"> removeAll(arg0 : Collection&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> retainAll(arg0 : Collection&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> batchRemove(arg0 : Collection&lt;?&gt;, arg1 : boolean) : boolean </td></tr><tr><td align="left" balign="left"> writeObject(arg0 : ObjectOutputStream) </td></tr><tr><td align="left" balign="left"> readObject(arg0 : ObjectInputStream) </td></tr><tr><td align="left" balign="left"> listIterator(arg0 : int) : ListIterator&lt;E&gt; </td></tr><tr><td align="left" balign="left"> listIterator() : ListIterator&lt;E&gt; </td></tr><tr><td align="left" balign="left"> iterator() : Iterator&lt;E&gt; </td></tr><tr><td align="left" balign="left"> subList(arg0 : int, arg1 : int) : List&lt;E&gt; </td></tr><tr><td align="left" balign="left"> subListRangeCheck(arg0 : int, arg1 : int, arg2 : int) </td></tr><tr><td align="left" balign="left"> forEach(arg0 : Consumer&lt;?&gt;) </td></tr><tr><td align="left" balign="left"> spliterator() : Spliterator&lt;E&gt; </td></tr><tr><td align="left" balign="left"> removeIf(arg0 : Predicate&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> replaceAll(arg0 : UnaryOperator&lt;E&gt;) </td></tr><tr><td align="left" balign="left"> sort(arg0 : Comparator&lt;?&gt;) </td></tr></table></td></tr></table>>, URL="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// A
c66 [label=<<table title="A" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> A </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> first : B </td></tr><tr><td align="left" balign="left"> second : B </td></tr><tr><td align="left" balign="left"> third : C </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// B
c67 [label=<<table title="B" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> B </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> doSomething(b : B, c : C) : A </td></tr></table></td></tr></table>>];
// C
c68 [label=<<table title="C" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> C </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> collectionOfA : List&lt;A&gt; </td></tr><tr><td align="left" balign="left"> collectionOfB : ArrayList&lt;B&gt; </td></tr><tr><td align="left" balign="left"> mapOfD : Map&lt;String, D&gt; </td></tr><tr><td align="left" balign="left"> childs : C[] </td></tr><tr><td align="left" balign="left"> anOpaqueList : List&lt;&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// MyFunnyList<T, V>
c69 [label=<<table title="MyFunnyList" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> MyFunnyList&lt;T, V&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> myField : V </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// MyList
c70 [label=<<table title="MyList" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> MyList </td></tr></table></td></tr></table>>];
// D
c71 [label=<<table title="D" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> D </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> anotherListOfA : MyList </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// MyFunnyList<T, V> extends java.util.ArrayList<T>
c72 -> c69 [arrowtail=empty,dir=back,weight=10];
// MyList extends MyFunnyList<A, B>
c69 -> c70 [arrowtail=empty,dir=back,weight=10];
// A has B
c66 -> c67 [arrowhead=none,arrowtail=ediamond,dir=back,weight=4];
// A has C
c66 -> c68 [arrowhead=none,arrowtail=ediamond,dir=back,weight=4];
// C navassoc B
c68 -> c67 [arrowhead=open,weight=1,headlabel="*"];
// C navassoc D
c68 -> c71 [arrowhead=open,weight=1,headlabel="*"];
// C navassoc C
c68 -> c68 [arrowhead=open,weight=1,headlabel="*"];
// C navassoc java.util.List<E>
c68 -> c73 [arrowhead=open,weight=1];
// D navassoc MyList
c71 -> c70 [arrowhead=open,weight=1];
// B depend A
c67 -> c66 [arrowhead=open,style=dashed,weight=0];
// java.util.List<E>
c73 [label=<<table title="java.util.List" border="0" cellborder="1" cellspacing="0" cellpadding="2" href="http://docs.oracle.com/javase/7/docs/api/java/util/List.html" target="_parent"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> List&lt;E&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"><i> size() : int </i></td></tr><tr><td align="left" balign="left"><i> isEmpty() : boolean </i></td></tr><tr><td align="left" balign="left"><i> contains(arg0 : Object) : boolean </i></td></tr><tr><td align="left" balign="left"><i> iterator() : Iterator&lt;E&gt; </i></td></tr><tr><td align="left" balign="left"><i> toArray() : Object[] </i></td></tr><tr><td align="left" balign="left"><i> toArray(arg0 : T[]) : T[] </i></td></tr><tr><td align="left" balign="left"><i> add(arg0 : E) : boolean </i></td></tr><tr><td align="left" balign="left"><i> remove(arg0 : Object) : boolean </i></td></tr><tr><td align="left" balign="left"><i> containsAll(arg0 : Collection&lt;?&gt;) : boolean </i></td></tr><tr><td align="left" balign="left"><i> addAll(arg0 : Collection&lt;?&gt;) : boolean </i></td></tr><tr><td align="left" balign="left"><i> addAll(arg0 : int, arg1 : Collection&lt;?&gt;) : boolean </i></td></tr><tr><td align="left" balign="left"><i> removeAll(arg0 : Collection&lt;?&gt;) : boolean </i></td></tr><tr><td align="left" balign="left"><i> retainAll(arg0 : Collection&lt;?&gt;) : boolean </i></td></tr><tr><td align="left" balign="left"> replaceAll(arg0 : UnaryOperator&lt;E&gt;) </td></tr><tr><td align="left" balign="left"> sort(arg0 : Comparator&lt;?&gt;) </td></tr><tr><td align="left" balign="left"><i> clear() </i></td></tr><tr><td align="left" balign="left"><i> equals(arg0 : Object) : boolean </i></td></tr><tr><td align="left" balign="left"><i> hashCode() : int </i></td></tr><tr><td align="left" balign="left"><i> get(arg0 : int) : E </i></td></tr><tr><td align="left" balign="left"><i> set(arg0 : int, arg1 : E) : E </i></td></tr><tr><td align="left" balign="left"><i> add(arg0 : int, arg1 : E) </i></td></tr><tr><td align="left" balign="left"><i> remove(arg0 : int) : E </i></td></tr><tr><td align="left" balign="left"><i> indexOf(arg0 : Object) : int </i></td></tr><tr><td align="left" balign="left"><i> lastIndexOf(arg0 : Object) : int </i></td></tr><tr><td align="left" balign="left"><i> listIterator() : ListIterator&lt;E&gt; </i></td></tr><tr><td align="left" balign="left"><i> listIterator(arg0 : int) : ListIterator&lt;E&gt; </i></td></tr><tr><td align="left" balign="left"><i> subList(arg0 : int, arg1 : int) : List&lt;E&gt; </i></td></tr><tr><td align="left" balign="left"> spliterator() : Spliterator&lt;E&gt; </td></tr></table></td></tr></table>>, URL="http://docs.oracle.com/javase/7/docs/api/java/util/List.html"];
// java.util.ArrayList<E>
c72 [label=<<table title="java.util.ArrayList" border="0" cellborder="1" cellspacing="0" cellpadding="2" href="http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html" target="_parent"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ArrayList&lt;E&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> serialVersionUID : long </td></tr><tr><td align="left" balign="left"> DEFAULT_CAPACITY : int </td></tr><tr><td align="left" balign="left"> EMPTY_ELEMENTDATA : Object[] </td></tr><tr><td align="left" balign="left"> DEFAULTCAPACITY_EMPTY_ELEMENTDATA : Object[] </td></tr><tr><td align="left" balign="left"> elementData : Object[] </td></tr><tr><td align="left" balign="left"> size : int </td></tr><tr><td align="left" balign="left"> MAX_ARRAY_SIZE : int </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> trimToSize() </td></tr><tr><td align="left" balign="left"> ensureCapacity(arg0 : int) </td></tr><tr><td align="left" balign="left"> ensureCapacityInternal(arg0 : int) </td></tr><tr><td align="left" balign="left"> ensureExplicitCapacity(arg0 : int) </td></tr><tr><td align="left" balign="left"> grow(arg0 : int) </td></tr><tr><td align="left" balign="left"> hugeCapacity(arg0 : int) : int </td></tr><tr><td align="left" balign="left"> size() : int </td></tr><tr><td align="left" balign="left"> isEmpty() : boolean </td></tr><tr><td align="left" balign="left"> contains(arg0 : Object) : boolean </td></tr><tr><td align="left" balign="left"> indexOf(arg0 : Object) : int </td></tr><tr><td align="left" balign="left"> lastIndexOf(arg0 : Object) : int </td></tr><tr><td align="left" balign="left"> clone() : Object </td></tr><tr><td align="left" balign="left"> toArray() : Object[] </td></tr><tr><td align="left" balign="left"> toArray(arg0 : T[]) : T[] </td></tr><tr><td align="left" balign="left"> elementData(arg0 : int) : E </td></tr><tr><td align="left" balign="left"> get(arg0 : int) : E </td></tr><tr><td align="left" balign="left"> set(arg0 : int, arg1 : E) : E </td></tr><tr><td align="left" balign="left"> add(arg0 : E) : boolean </td></tr><tr><td align="left" balign="left"> add(arg0 : int, arg1 : E) </td></tr><tr><td align="left" balign="left"> remove(arg0 : int) : E </td></tr><tr><td align="left" balign="left"> remove(arg0 : Object) : boolean </td></tr><tr><td align="left" balign="left"> fastRemove(arg0 : int) </td></tr><tr><td align="left" balign="left"> clear() </td></tr><tr><td align="left" balign="left"> addAll(arg0 : Collection&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> addAll(arg0 : int, arg1 : Collection&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> removeRange(arg0 : int, arg1 : int) </td></tr><tr><td align="left" balign="left"> rangeCheck(arg0 : int) </td></tr><tr><td align="left" balign="left"> rangeCheckForAdd(arg0 : int) </td></tr><tr><td align="left" balign="left"> outOfBoundsMsg(arg0 : int) : String </td></tr><tr><td align="left" balign="left"> removeAll(arg0 : Collection&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> retainAll(arg0 : Collection&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> batchRemove(arg0 : Collection&lt;?&gt;, arg1 : boolean) : boolean </td></tr><tr><td align="left" balign="left"> writeObject(arg0 : ObjectOutputStream) </td></tr><tr><td align="left" balign="left"> readObject(arg0 : ObjectInputStream) </td></tr><tr><td align="left" balign="left"> listIterator(arg0 : int) : ListIterator&lt;E&gt; </td></tr><tr><td align="left" balign="left"> listIterator() : ListIterator&lt;E&gt; </td></tr><tr><td align="left" balign="left"> iterator() : Iterator&lt;E&gt; </td></tr><tr><td align="left" balign="left"> subList(arg0 : int, arg1 : int) : List&lt;E&gt; </td></tr><tr><td align="left" balign="left"> subListRangeCheck(arg0 : int, arg1 : int, arg2 : int) </td></tr><tr><td align="left" balign="left"> forEach(arg0 : Consumer&lt;?&gt;) </td></tr><tr><td align="left" balign="left"> spliterator() : Spliterator&lt;E&gt; </td></tr><tr><td align="left" balign="left"> removeIf(arg0 : Predicate&lt;?&gt;) : boolean </td></tr><tr><td align="left" balign="left"> replaceAll(arg0 : UnaryOperator&lt;E&gt;) </td></tr><tr><td align="left" balign="left"> sort(arg0 : Comparator&lt;?&gt;) </td></tr></table></td></tr></table>>, URL="http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html"];
}

View File

@ -5,19 +5,20 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Application
c74 [label=<<table title="Application" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Application </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// IrpApplication
c75 [label=<<table title="IrpApplication" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> IrpApplication </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Main
c76 [label=<<table title="Main" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Main </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//IrpApplication extends Application
c74:p -> c75:p [dir=back,arrowtail=empty];
// Main DEPEND IrpApplication
c76:p -> c75:p [taillabel="", label="&#171;friend&#187;", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open, style=dashed];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Application
c74 [label=<<table title="Application" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Application </td></tr></table></td></tr></table>>];
// IrpApplication
c75 [label=<<table title="IrpApplication" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> IrpApplication </td></tr></table></td></tr></table>>];
// Main
c76 [label=<<table title="Main" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Main </td></tr></table></td></tr></table>>];
// IrpApplication extends Application
c74 -> c75 [arrowtail=empty,dir=back,weight=10];
// Main depend IrpApplication
c76 -> c75 [arrowhead=open,style=dashed,weight=0,label="&#171;friend&#187;"];
}

View File

@ -5,15 +5,16 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// A
c81 [label=<<table title="A" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> A </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// C
c83 [label=<<table title="C" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> C </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// A DEPEND C
c81:p -> c83:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open, style=dashed];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// A
c81 [label=<<table title="A" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> A </td></tr></table></td></tr></table>>];
// C
c83 [label=<<table title="C" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> C </td></tr></table></td></tr></table>>];
// A depend C
c81 -> c83 [arrowhead=open,style=dashed,weight=0];
}

File diff suppressed because one or more lines are too long

View File

@ -5,43 +5,44 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Root
c90 [label=<<table title="Root" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Root </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Adapter
c91 [label=<<table title="Adapter" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Adapter </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Element
c92 [label=<<table title="Element" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="Helvetica-Oblique"> Element </font></td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// ObjectType
c93 [label=<<table title="ObjectType" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ObjectType </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// ObjectMap
c94 [label=<<table title="ObjectMap" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ObjectMap </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Table
c95 [label=<<table title="Table" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Table </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// DataOperation
c96 [label=<<table title="DataOperation" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> DataOperation </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Root ASSOC Adapter
c90:p -> c91:p [taillabel="1..1", label="", headlabel="0..n", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// Root ASSOC ObjectType
c90:p -> c93:p [taillabel="", label="", headlabel="0..n", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// Root ASSOC ObjectMap
c90:p -> c94:p [taillabel="", label="", headlabel="0..n", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// Root ASSOC Table
c90:p -> c95:p [taillabel="", label="", headlabel="0..n", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// Root ASSOC DataOperation
c90:p -> c96:p [taillabel="", label="", headlabel="0..n", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
//ObjectType extends Element
c92:p -> c93:p [dir=back,arrowtail=empty];
//ObjectMap extends Element
c92:p -> c94:p [dir=back,arrowtail=empty];
// ObjectMap HAS ObjectType
c94:p -> c93:p [taillabel="1..1", label="", headlabel="1..1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=ediamond, dir=both];
//Table extends Element
c92:p -> c95:p [dir=back,arrowtail=empty];
//DataOperation extends Element
c92:p -> c96:p [dir=back,arrowtail=empty];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Root
c90 [label=<<table title="Root" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Root </td></tr></table></td></tr></table>>];
// Adapter
c91 [label=<<table title="Adapter" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Adapter </td></tr></table></td></tr></table>>];
// Element
c92 [label=<<table title="Element" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><i> Element </i></td></tr></table></td></tr></table>>];
// ObjectType
c93 [label=<<table title="ObjectType" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ObjectType </td></tr></table></td></tr></table>>];
// ObjectMap
c94 [label=<<table title="ObjectMap" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ObjectMap </td></tr></table></td></tr></table>>];
// Table
c95 [label=<<table title="Table" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Table </td></tr></table></td></tr></table>>];
// DataOperation
c96 [label=<<table title="DataOperation" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> DataOperation </td></tr></table></td></tr></table>>];
// Root assoc Adapter
c90 -> c91 [arrowhead=none,weight=2,taillabel="1..1", headlabel="0..n"];
// Root assoc ObjectType
c90 -> c93 [arrowhead=none,weight=2,headlabel="0..n"];
// Root assoc ObjectMap
c90 -> c94 [arrowhead=none,weight=2,headlabel="0..n"];
// Root assoc Table
c90 -> c95 [arrowhead=none,weight=2,headlabel="0..n"];
// Root assoc DataOperation
c90 -> c96 [arrowhead=none,weight=2,headlabel="0..n"];
// ObjectType extends Element
c92 -> c93 [arrowtail=empty,dir=back,weight=10];
// ObjectMap extends Element
c92 -> c94 [arrowtail=empty,dir=back,weight=10];
// ObjectMap has ObjectType
c94 -> c93 [arrowhead=none,arrowtail=ediamond,dir=back,weight=4,taillabel="1..1", headlabel="1..1"];
// Table extends Element
c92 -> c95 [arrowtail=empty,dir=back,weight=10];
// DataOperation extends Element
c92 -> c96 [arrowtail=empty,dir=back,weight=10];
}

View File

@ -1,19 +1,20 @@
#!/usr/local/bin/dot
#
# Class diagram
# Generated by UMLGraph version R5_6-9-g37cd34 (http://www.umlgraph.org/)
# Generated by UMLGraph version R5_7_2-10-g442559 (http://www.umlgraph.org/)
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// test.RunnableRef
c98 [label=<<table title="test.RunnableRef" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> RunnableRef </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// test.RunnableRef DEPEND java.lang.Runnable
c98:p -> c99:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open, style=dashed];
// java.lang.Runnable
c99 [label=<<table title="java.lang.Runnable" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runnable.html"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> Runnable </td></tr></table></td></tr></table>>, URL="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runnable.html", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// test.RunnableRef
c98 [label=<<table title="test.RunnableRef" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> RunnableRef </td></tr></table></td></tr></table>>];
// test.RunnableRef depend java.lang.Runnable
c98 -> c99 [arrowhead=open,style=dashed,weight=0];
// java.lang.Runnable
c99 [label=<<table title="java.lang.Runnable" border="0" cellborder="1" cellspacing="0" cellpadding="2" href="http://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html" target="_parent"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> Runnable </td></tr></table></td></tr></table>>, URL="http://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html"];
}

View File

@ -1,27 +1,28 @@
#!/usr/local/bin/dot
#
# Class diagram
# Generated by UMLGraph version R5_6-9-g37cd34 (http://www.umlgraph.org/)
# Generated by UMLGraph version R5_7_2-10-g442559 (http://www.umlgraph.org/)
#
digraph G {
edge [fontname="arial",fontsize=10,labelfontname="arial",labelfontsize=10];
node [fontname="arial",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// net.sf.whatever.test.AbstractBase
c112 [label=<<table title="net.sf.whatever.test.AbstractBase" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;base&#187; </td></tr><tr><td align="center" balign="center"><font face="arial"> AbstractBase </font></td></tr><tr><td align="center" balign="center"><font point-size="8.0"> net.sf.whatever.test </font></td></tr><tr><td align="right" balign="right"><font face="arial" point-size="6.0"> {since = 1.0} </font></td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> field : int </td></tr><tr><td align="right" balign="right"><font face="arial" point-size="6.0"> {since = 1.5} </font></td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="9.0"> abstractMethod() </font></td></tr><tr><td align="left" balign="left"> concreteMethod() : int </td></tr></table></td></tr></table>>, URL="null", fontname="arial", fontcolor="black", fontsize=9.0];
// net.sf.whatever.test.Composite
c113 [label=<<table title="net.sf.whatever.test.Composite" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="arial"> Composite </font></td></tr><tr><td align="center" balign="center"><font point-size="8.0"> net.sf.whatever.test </font></td></tr></table></td></tr></table>>, URL="null", fontname="arial", fontcolor="black", fontsize=9.0];
// net.sf.whatever.test.Style
c114 [label=<<table title="net.sf.whatever.test.Style" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="arial"> Style </font></td></tr><tr><td align="center" balign="center"><font point-size="8.0"> net.sf.whatever.test </font></td></tr></table></td></tr></table>>, URL="null", fontname="arial", fontcolor="black", fontsize=9.0];
//net.sf.whatever.test.Composite extends net.sf.whatever.test.AbstractBase
c112:p -> c113:p [dir=back,arrowtail=empty];
// net.sf.whatever.test.Composite COMPOSED from.Outer.Space.AlienClass
c113:p -> c115:p [taillabel="1", label="has", headlabel="*", fontname="arial", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
//net.sf.whatever.test.Style extends net.sf.whatever.test.AbstractBase
c112:p -> c114:p [dir=back,arrowtail=empty];
// from.Outer.Space.AlienClass
c115[label=<<table title="from.Outer.Space.AlienClass" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" href="http://java.sun.com/j2se/1.4.2/docs/api/from/Outer/Space/AlienClass.html"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="arial"> AlienClass </font></td></tr><tr><td align="center" balign="center"><font point-size="8.0"> from.Outer.Space </font></td></tr></table></td></tr></table>>, fontname="arial", fontcolor="black", fontsize=9.0];
graph [fontnames="svg"]
edge [fontname="arial",fontsize=10,labelfontname="arial",labelfontsize=10,color="black"];
node [fontname="arial",fontcolor="black",fontsize=9,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// net.sf.whatever.test.AbstractBase
c112 [label=<<table title="net.sf.whatever.test.AbstractBase" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;base&#187; </td></tr><tr><td align="center" balign="center"><font face="arial"> AbstractBase </font></td></tr><tr><td align="center" balign="center"><font point-size="8.0"> net.sf.whatever.test </font></td></tr><tr><td align="right" balign="right"><font face="arial" point-size="6.0"> {since = 1.0} </font></td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> field : int </td></tr><tr><td align="right" balign="right"><font face="arial" point-size="6.0"> {since = 1.5} </font></td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"><i> abstractMethod() </i></td></tr><tr><td align="left" balign="left"> concreteMethod() : int </td></tr></table></td></tr></table>>];
// net.sf.whatever.test.Composite
c113 [label=<<table title="net.sf.whatever.test.Composite" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="arial"> Composite </font></td></tr><tr><td align="center" balign="center"><font point-size="8.0"> net.sf.whatever.test </font></td></tr></table></td></tr></table>>];
// net.sf.whatever.test.Style
c114 [label=<<table title="net.sf.whatever.test.Style" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="arial"> Style </font></td></tr><tr><td align="center" balign="center"><font point-size="8.0"> net.sf.whatever.test </font></td></tr></table></td></tr></table>>];
// net.sf.whatever.test.Composite extends net.sf.whatever.test.AbstractBase
c112 -> c113 [arrowtail=empty,dir=back,weight=10];
// net.sf.whatever.test.Composite composed from.Outer.Space.AlienClass
c113 -> c115 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1",label="has",headlabel="*"];
// net.sf.whatever.test.Style extends net.sf.whatever.test.AbstractBase
c112 -> c114 [arrowtail=empty,dir=back,weight=10];
// from.Outer.Space.AlienClass
c115[label=<<table title="from.Outer.Space.AlienClass" border="0" cellborder="1" cellspacing="0" cellpadding="2" href="http://docs.oracle.com/javase/7/docs/api/from/Outer.Space.AlienClass.html" target="_parent"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="arial"> AlienClass </font></td></tr><tr><td align="center" balign="center"><font point-size="8.0"> from.Outer.Space </font></td></tr></table></td></tr></table>>];
}

View File

@ -5,11 +5,12 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// test.TestHideOp
c117 [label=<<table title="test.TestHideOp" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> TestHideOp </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// test.TestHideOp
c117 [label=<<table title="test.TestHideOp" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> TestHideOp </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
}

View File

@ -5,27 +5,28 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.invoice.InvoiceItem
c355 [label=<<table title="gr.spinellis.basic.invoice.InvoiceItem" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InvoiceItem </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.Invoice
c356 [label=<<table title="gr.spinellis.basic.invoice.Invoice" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Invoice </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.Customer
c357 [label=<<table title="gr.spinellis.basic.invoice.Customer" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Customer </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Product
c358 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Category
c359 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.InvoiceItem ASSOC gr.spinellis.basic.product.Product
c355:p -> c358:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.invoice.Invoice ASSOC gr.spinellis.basic.invoice.Customer
c356:p -> c357:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.invoice.Invoice COMPOSED gr.spinellis.basic.invoice.InvoiceItem
c356:p -> c355:p [taillabel="1", label="", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
// gr.spinellis.basic.product.Product ASSOC gr.spinellis.basic.product.Category
c358:p -> c359:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.invoice.InvoiceItem
c355 [label=<<table title="gr.spinellis.basic.invoice.InvoiceItem" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InvoiceItem </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.Invoice
c356 [label=<<table title="gr.spinellis.basic.invoice.Invoice" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Invoice </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.Customer
c357 [label=<<table title="gr.spinellis.basic.invoice.Customer" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Customer </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Product
c358 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Category
c359 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.InvoiceItem assoc gr.spinellis.basic.product.Product
c355 -> c358 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.invoice.Invoice assoc gr.spinellis.basic.invoice.Customer
c356 -> c357 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.invoice.Invoice composed gr.spinellis.basic.invoice.InvoiceItem
c356 -> c355 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1", headlabel="*"];
// gr.spinellis.basic.product.Product assoc gr.spinellis.basic.product.Category
c358 -> c359 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
}

View File

@ -5,27 +5,28 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.invoice.InvoiceItem
c317 [label=<<table title="gr.spinellis.basic.invoice.InvoiceItem" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InvoiceItem </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> product : Product </td></tr><tr><td align="left" balign="left"> quantity : int </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.Invoice
c318 [label=<<table title="gr.spinellis.basic.invoice.Invoice" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Invoice </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> total : double </td></tr><tr><td align="left" balign="left"> items : InvoiceItem[] </td></tr><tr><td align="left" balign="left"> customer : Customer </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> addItem(p : Product, quantity : int) </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.Customer
c319 [label=<<table title="gr.spinellis.basic.invoice.Customer" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Customer </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : String </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Product
c320 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : String </td></tr><tr><td align="left" balign="left"> stock : int </td></tr><tr><td align="left" balign="left"> price : double </td></tr><tr><td align="left" balign="left"> category : Category </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Category
c321 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : String </td></tr><tr><td align="left" balign="left"> products : List&lt;&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.InvoiceItem ASSOC gr.spinellis.basic.product.Product
c317:p -> c320:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.invoice.Invoice ASSOC gr.spinellis.basic.invoice.Customer
c318:p -> c319:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.invoice.Invoice COMPOSED gr.spinellis.basic.invoice.InvoiceItem
c318:p -> c317:p [taillabel="1", label="", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
// gr.spinellis.basic.product.Product ASSOC gr.spinellis.basic.product.Category
c320:p -> c321:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.invoice.InvoiceItem
c317 [label=<<table title="gr.spinellis.basic.invoice.InvoiceItem" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InvoiceItem </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> product : Product </td></tr><tr><td align="left" balign="left"> quantity : int </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.Invoice
c318 [label=<<table title="gr.spinellis.basic.invoice.Invoice" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Invoice </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> total : double </td></tr><tr><td align="left" balign="left"> items : InvoiceItem[] </td></tr><tr><td align="left" balign="left"> customer : Customer </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> addItem(p : Product, quantity : int) </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.Customer
c319 [label=<<table title="gr.spinellis.basic.invoice.Customer" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Customer </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : String </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Product
c320 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : String </td></tr><tr><td align="left" balign="left"> stock : int </td></tr><tr><td align="left" balign="left"> price : double </td></tr><tr><td align="left" balign="left"> category : Category </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Category
c321 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : String </td></tr><tr><td align="left" balign="left"> products : List&lt;&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.InvoiceItem assoc gr.spinellis.basic.product.Product
c317 -> c320 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.invoice.Invoice assoc gr.spinellis.basic.invoice.Customer
c318 -> c319 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.invoice.Invoice composed gr.spinellis.basic.invoice.InvoiceItem
c318 -> c317 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1", headlabel="*"];
// gr.spinellis.basic.product.Product assoc gr.spinellis.basic.product.Category
c320 -> c321 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
}

View File

@ -5,27 +5,28 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.invoice.InvoiceItem
c279 [label=<<table title="gr.spinellis.basic.invoice.InvoiceItem" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InvoiceItem </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> product </td></tr><tr><td align="left" balign="left"> quantity </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.invoice.Invoice
c280 [label=<<table title="gr.spinellis.basic.invoice.Invoice" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Invoice </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> total </td></tr><tr><td align="left" balign="left"> items </td></tr><tr><td align="left" balign="left"> customer </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.invoice.Customer
c281 [label=<<table title="gr.spinellis.basic.invoice.Customer" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Customer </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.product.Product
c282 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> stock </td></tr><tr><td align="left" balign="left"> price </td></tr><tr><td align="left" balign="left"> category </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.product.Category
c283 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> products </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.invoice.InvoiceItem ASSOC gr.spinellis.basic.product.Product
c279:p -> c282:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.invoice.Invoice ASSOC gr.spinellis.basic.invoice.Customer
c280:p -> c281:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.invoice.Invoice COMPOSED gr.spinellis.basic.invoice.InvoiceItem
c280:p -> c279:p [taillabel="1", label="", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
// gr.spinellis.basic.product.Product ASSOC gr.spinellis.basic.product.Category
c282:p -> c283:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.invoice.InvoiceItem
c279 [label=<<table title="gr.spinellis.basic.invoice.InvoiceItem" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InvoiceItem </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> product </td></tr><tr><td align="left" balign="left"> quantity </td></tr></table></td></tr></table>>, fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.invoice.Invoice
c280 [label=<<table title="gr.spinellis.basic.invoice.Invoice" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Invoice </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> total </td></tr><tr><td align="left" balign="left"> items </td></tr><tr><td align="left" balign="left"> customer </td></tr></table></td></tr></table>>, fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.invoice.Customer
c281 [label=<<table title="gr.spinellis.basic.invoice.Customer" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Customer </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr></table></td></tr></table>>, fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.product.Product
c282 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> stock </td></tr><tr><td align="left" balign="left"> price </td></tr><tr><td align="left" balign="left"> category </td></tr></table></td></tr></table>>, fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.product.Category
c283 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> products </td></tr></table></td></tr></table>>, fontname="Helvetica", fontcolor="black", fontsize=16.0];
// gr.spinellis.basic.invoice.InvoiceItem assoc gr.spinellis.basic.product.Product
c279 -> c282 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.invoice.Invoice assoc gr.spinellis.basic.invoice.Customer
c280 -> c281 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.invoice.Invoice composed gr.spinellis.basic.invoice.InvoiceItem
c280 -> c279 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1", headlabel="*"];
// gr.spinellis.basic.product.Product assoc gr.spinellis.basic.product.Category
c282 -> c283 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
}

View File

@ -5,15 +5,16 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.product.Product
c244 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="LemonChiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Category
c245 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="LemonChiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Product ASSOC gr.spinellis.basic.product.Category
c244:p -> c245:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.product.Product
c244 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="LemonChiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Category
c245 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="LemonChiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Product assoc gr.spinellis.basic.product.Category
c244 -> c245 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
}

View File

@ -5,15 +5,16 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.product.Product
c206 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="LemonChiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> stock </td></tr><tr><td align="left" balign="left"> price </td></tr><tr><td align="left" balign="left"> category </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Category
c207 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="brown"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Product ASSOC gr.spinellis.basic.product.Category
c206:p -> c207:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.product.Product
c206 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="LemonChiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> stock </td></tr><tr><td align="left" balign="left"> price </td></tr><tr><td align="left" balign="left"> category </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Category
c207 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="brown"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Product assoc gr.spinellis.basic.product.Category
c206 -> c207 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
}

View File

@ -1,35 +1,36 @@
#!/usr/local/bin/dot
#
# Class diagram
# Generated by UMLGraph version R5_6-9-g37cd34 (http://www.umlgraph.org/)
# Generated by UMLGraph version R5_7_2-10-g442559 (http://www.umlgraph.org/)
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.invoice.InvoiceItem
c164 [label=<<table title="gr.spinellis.basic.invoice.InvoiceItem" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InvoiceItem </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.Invoice
c165 [label=<<table title="gr.spinellis.basic.invoice.Invoice" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Invoice </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.Customer
c166 [label=<<table title="gr.spinellis.basic.invoice.Customer" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Customer </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Product
c167 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Category
c168 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.invoice.InvoiceItem ASSOC gr.spinellis.basic.product.Product
c164:p -> c167:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.invoice.Invoice ASSOC gr.spinellis.basic.invoice.Customer
c165:p -> c166:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.invoice.Invoice COMPOSED gr.spinellis.basic.invoice.InvoiceItem
c165:p -> c164:p [taillabel="1", label="", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
// gr.spinellis.basic.product.Product ASSOC gr.spinellis.basic.product.Category
c167:p -> c168:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// gr.spinellis.basic.product.Category DEPEND java.util.List<E>
c168:p -> c202:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open, style=dashed];
// java.util.List<E>
c202 [label=<<table title="java.util.List" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="gray" href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> List&lt;E&gt; </td></tr></table></td></tr></table>>, URL="http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.invoice.InvoiceItem
c164 [label=<<table title="gr.spinellis.basic.invoice.InvoiceItem" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InvoiceItem </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.Invoice
c165 [label=<<table title="gr.spinellis.basic.invoice.Invoice" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Invoice </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.Customer
c166 [label=<<table title="gr.spinellis.basic.invoice.Customer" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Customer </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Product
c167 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Category
c168 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="yellow"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.invoice.InvoiceItem assoc gr.spinellis.basic.product.Product
c164 -> c167 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.invoice.Invoice assoc gr.spinellis.basic.invoice.Customer
c165 -> c166 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.invoice.Invoice composed gr.spinellis.basic.invoice.InvoiceItem
c165 -> c164 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1", headlabel="*"];
// gr.spinellis.basic.product.Product assoc gr.spinellis.basic.product.Category
c167 -> c168 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
// gr.spinellis.basic.product.Category depend java.util.List<E>
c168 -> c202 [arrowhead=open,style=dashed,weight=0];
// java.util.List<E>
c202 [label=<<table title="java.util.List" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="gray" href="http://docs.oracle.com/javase/7/docs/api/java/util/List.html" target="_parent"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> List&lt;E&gt; </td></tr></table></td></tr></table>>, URL="http://docs.oracle.com/javase/7/docs/api/java/util/List.html"];
}

View File

@ -1,43 +1,44 @@
#!/usr/local/bin/dot
#
# Class diagram
# Generated by UMLGraph version R5_7_0-10-g786d98 (http://www.umlgraph.org/)
# Generated by UMLGraph version R5_7_2-10-g442559 (http://www.umlgraph.org/)
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.context.classes.AClient
c424 [label=<<table title="gr.spinellis.context.classes.AClient" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> AClient </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.context.classes.ASubclass
c426 [label=<<table title="gr.spinellis.context.classes.ASubclass" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ASubclass </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.context.classes.E
c427 [label=<<table title="gr.spinellis.context.classes.E" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> E </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.context.classes.D
c429 [label=<<table title="gr.spinellis.context.classes.D" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> D </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.context.classes.B
c432 [label=<<table title="gr.spinellis.context.classes.B" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> B </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.context.classes.ABaseClass
c433 [label=<<table title="gr.spinellis.context.classes.ABaseClass" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ABaseClass </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.context.classes.A
c434 [label=<<table title="gr.spinellis.context.classes.A" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="lemonchiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> A </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//gr.spinellis.context.classes.ASubclass extends gr.spinellis.context.classes.A
c434:p -> c426:p [dir=back,arrowtail=empty];
//gr.spinellis.context.classes.A extends gr.spinellis.context.classes.ABaseClass
c433:p -> c434:p [dir=back,arrowtail=empty];
// gr.spinellis.context.classes.D NAVASSOC gr.spinellis.context.classes.A
c429:p -> c434:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// gr.spinellis.context.classes.A NAVASSOC gr.spinellis.context.classes.B
c434:p -> c432:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// gr.spinellis.context.classes.A NAVASSOC javax.swing.JComponent
c434:p -> c508:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// gr.spinellis.context.classes.AClient DEPEND gr.spinellis.context.classes.A
c424:p -> c434:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open, style=dashed];
// gr.spinellis.context.classes.A DEPEND gr.spinellis.context.classes.E
c434:p -> c427:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open, style=dashed];
// javax.swing.JComponent
c508 [label=<<table title="javax.swing.JComponent" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComponent.html"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="Helvetica-Oblique"> JComponent </font></td></tr></table></td></tr></table>>, URL="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComponent.html", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.context.classes.AClient
c424 [label=<<table title="gr.spinellis.context.classes.AClient" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> AClient </td></tr></table></td></tr></table>>];
// gr.spinellis.context.classes.ASubclass
c426 [label=<<table title="gr.spinellis.context.classes.ASubclass" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ASubclass </td></tr></table></td></tr></table>>];
// gr.spinellis.context.classes.E
c427 [label=<<table title="gr.spinellis.context.classes.E" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> E </td></tr></table></td></tr></table>>];
// gr.spinellis.context.classes.D
c429 [label=<<table title="gr.spinellis.context.classes.D" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> D </td></tr></table></td></tr></table>>];
// gr.spinellis.context.classes.B
c432 [label=<<table title="gr.spinellis.context.classes.B" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> B </td></tr></table></td></tr></table>>];
// gr.spinellis.context.classes.ABaseClass
c433 [label=<<table title="gr.spinellis.context.classes.ABaseClass" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ABaseClass </td></tr></table></td></tr></table>>];
// gr.spinellis.context.classes.A
c434 [label=<<table title="gr.spinellis.context.classes.A" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="lemonchiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> A </td></tr></table></td></tr></table>>];
// gr.spinellis.context.classes.ASubclass extends gr.spinellis.context.classes.A
c434 -> c426 [arrowtail=empty,dir=back,weight=10];
// gr.spinellis.context.classes.A extends gr.spinellis.context.classes.ABaseClass
c433 -> c434 [arrowtail=empty,dir=back,weight=10];
// gr.spinellis.context.classes.D navassoc gr.spinellis.context.classes.A
c429 -> c434 [arrowhead=open,weight=1];
// gr.spinellis.context.classes.A navassoc gr.spinellis.context.classes.B
c434 -> c432 [arrowhead=open,weight=1];
// gr.spinellis.context.classes.A navassoc javax.swing.JComponent
c434 -> c509 [arrowhead=open,weight=1];
// gr.spinellis.context.classes.AClient depend gr.spinellis.context.classes.A
c424 -> c434 [arrowhead=open,style=dashed,weight=0];
// gr.spinellis.context.classes.A depend gr.spinellis.context.classes.E
c434 -> c427 [arrowhead=open,style=dashed,weight=0];
// javax.swing.JComponent
c509 [label=<<table title="javax.swing.JComponent" border="0" cellborder="1" cellspacing="0" cellpadding="2" href="http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html" target="_parent"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><i> JComponent </i></td></tr></table></td></tr></table>>, URL="http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html"];
}

View File

@ -1,31 +1,32 @@
#!/usr/local/bin/dot
#
# Class diagram
# Generated by UMLGraph version R5_7_0-10-g786d98 (http://www.umlgraph.org/)
# Generated by UMLGraph version R5_7_2-20-g09fab1 (http://www.umlgraph.org/)
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.iface.classes.FarImplementor
c533 [label=<<table title="gr.spinellis.iface.classes.FarImplementor" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> FarImplementor </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.iface.classes.DirectImplementor
c534 [label=<<table title="gr.spinellis.iface.classes.DirectImplementor" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> DirectImplementor </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.iface.classes.SubSubFace
c536 [label=<<table title="gr.spinellis.iface.classes.SubSubFace" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> SubSubFace </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.iface.classes.SubFace
c537 [label=<<table title="gr.spinellis.iface.classes.SubFace" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> SubFace </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.iface.classes.Face
c538 [label=<<table title="gr.spinellis.iface.classes.Face" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="lemonchiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> Face </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//gr.spinellis.iface.classes.FarImplementor implements gr.spinellis.iface.classes.SubSubFace
c536:p -> c533:p [dir=back,arrowtail=empty,style=dashed];
//gr.spinellis.iface.classes.DirectImplementor implements gr.spinellis.iface.classes.Face
c538:p -> c534:p [dir=back,arrowtail=empty,style=dashed];
//gr.spinellis.iface.classes.SubSubFace implements gr.spinellis.iface.classes.SubFace
c537:p -> c536:p [dir=back,arrowtail=empty,style=dashed];
//gr.spinellis.iface.classes.SubFace implements gr.spinellis.iface.classes.Face
c538:p -> c537:p [dir=back,arrowtail=empty,style=dashed];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.iface.classes.FarImplementor
c534 [label=<<table title="gr.spinellis.iface.classes.FarImplementor" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> FarImplementor </td></tr></table></td></tr></table>>];
// gr.spinellis.iface.classes.DirectImplementor
c535 [label=<<table title="gr.spinellis.iface.classes.DirectImplementor" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> DirectImplementor </td></tr></table></td></tr></table>>];
// gr.spinellis.iface.classes.SubSubFace
c537 [label=<<table title="gr.spinellis.iface.classes.SubSubFace" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> SubSubFace </td></tr></table></td></tr></table>>];
// gr.spinellis.iface.classes.SubFace
c538 [label=<<table title="gr.spinellis.iface.classes.SubFace" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> SubFace </td></tr></table></td></tr></table>>];
// gr.spinellis.iface.classes.Face
c539 [label=<<table title="gr.spinellis.iface.classes.Face" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="lemonchiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> Face </td></tr></table></td></tr></table>>];
// gr.spinellis.iface.classes.FarImplementor implements gr.spinellis.iface.classes.SubSubFace
c537 -> c534 [arrowtail=empty,style=dashed,dir=back,weight=9];
// gr.spinellis.iface.classes.DirectImplementor implements gr.spinellis.iface.classes.Face
c539 -> c535 [arrowtail=empty,style=dashed,dir=back,weight=9];
// gr.spinellis.iface.classes.SubSubFace implements gr.spinellis.iface.classes.SubFace
c538 -> c537 [arrowtail=empty,style=dashed,dir=back,weight=9];
// gr.spinellis.iface.classes.SubFace implements gr.spinellis.iface.classes.Face
c539 -> c538 [arrowtail=empty,style=dashed,dir=back,weight=9];
}

View File

@ -5,15 +5,16 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.product.Product
c129 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> stock </td></tr><tr><td align="left" balign="left"> price </td></tr><tr><td align="left" balign="left"> category </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Category
c130 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> products </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.basic.product.Product ASSOC gr.spinellis.basic.product.Category
c129:p -> c130:p [taillabel="*", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.basic.product.Product
c129 [label=<<table title="gr.spinellis.basic.product.Product" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Product </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> stock </td></tr><tr><td align="left" balign="left"> price </td></tr><tr><td align="left" balign="left"> category </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Category
c130 [label=<<table title="gr.spinellis.basic.product.Category" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Category </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name </td></tr><tr><td align="left" balign="left"> products </td></tr></table></td></tr></table>>];
// gr.spinellis.basic.product.Product assoc gr.spinellis.basic.product.Category
c129 -> c130 [arrowhead=none,weight=2,taillabel="*", headlabel="1"];
}

View File

@ -1,31 +1,32 @@
#!/usr/local/bin/dot
#
# Class diagram
# Generated by UMLGraph version R5_7_0-10-g786d98 (http://www.umlgraph.org/)
# Generated by UMLGraph version R5_7_2-20-g09fab1 (http://www.umlgraph.org/)
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.subclass.classes.SubOneTwo
c579 [label=<<table title="gr.spinellis.subclass.classes.SubOneTwo" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SubOneTwo </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.subclass.classes.SubOneOne
c580 [label=<<table title="gr.spinellis.subclass.classes.SubOneOne" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SubOneOne </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.subclass.classes.SubTwo
c581 [label=<<table title="gr.spinellis.subclass.classes.SubTwo" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SubTwo </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.subclass.classes.SubOne
c582 [label=<<table title="gr.spinellis.subclass.classes.SubOne" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SubOne </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// gr.spinellis.subclass.classes.Super
c583 [label=<<table title="gr.spinellis.subclass.classes.Super" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="lemonchiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Super </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//gr.spinellis.subclass.classes.SubOneTwo extends gr.spinellis.subclass.classes.SubOne
c582:p -> c579:p [dir=back,arrowtail=empty];
//gr.spinellis.subclass.classes.SubOneOne extends gr.spinellis.subclass.classes.SubOne
c582:p -> c580:p [dir=back,arrowtail=empty];
//gr.spinellis.subclass.classes.SubTwo extends gr.spinellis.subclass.classes.Super
c583:p -> c581:p [dir=back,arrowtail=empty];
//gr.spinellis.subclass.classes.SubOne extends gr.spinellis.subclass.classes.Super
c583:p -> c582:p [dir=back,arrowtail=empty];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// gr.spinellis.subclass.classes.SubOneTwo
c580 [label=<<table title="gr.spinellis.subclass.classes.SubOneTwo" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SubOneTwo </td></tr></table></td></tr></table>>];
// gr.spinellis.subclass.classes.SubOneOne
c581 [label=<<table title="gr.spinellis.subclass.classes.SubOneOne" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SubOneOne </td></tr></table></td></tr></table>>];
// gr.spinellis.subclass.classes.SubTwo
c582 [label=<<table title="gr.spinellis.subclass.classes.SubTwo" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SubTwo </td></tr></table></td></tr></table>>];
// gr.spinellis.subclass.classes.SubOne
c583 [label=<<table title="gr.spinellis.subclass.classes.SubOne" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SubOne </td></tr></table></td></tr></table>>];
// gr.spinellis.subclass.classes.Super
c584 [label=<<table title="gr.spinellis.subclass.classes.Super" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="lemonchiffon"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Super </td></tr></table></td></tr></table>>];
// gr.spinellis.subclass.classes.SubOneTwo extends gr.spinellis.subclass.classes.SubOne
c583 -> c580 [arrowtail=empty,dir=back,weight=10];
// gr.spinellis.subclass.classes.SubOneOne extends gr.spinellis.subclass.classes.SubOne
c583 -> c581 [arrowtail=empty,dir=back,weight=10];
// gr.spinellis.subclass.classes.SubTwo extends gr.spinellis.subclass.classes.Super
c584 -> c582 [arrowtail=empty,dir=back,weight=10];
// gr.spinellis.subclass.classes.SubOne extends gr.spinellis.subclass.classes.Super
c584 -> c583 [arrowtail=empty,dir=back,weight=10];
}

16
testdata/dot-ref/active.dot vendored Normal file
View File

@ -0,0 +1,16 @@
#!/usr/local/bin/dot
#
# Class diagram
# Generated by UMLGraph version R5_7_2-54-gbca0ce (http://www.spinellis.gr/umlgraph/)
#
digraph G {
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Active
c32 [label=<<table title="Active" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td rowspan="10"></td><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Active </td></tr></table></td><td rowspan="10"></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> run() </td></tr></table></td></tr></table>>];
}

View File

@ -5,31 +5,32 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Controller
c5 [label=<<table title="Controller" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Controller </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// EmbeddedAgent
c6 [label=<<table title="EmbeddedAgent" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> EmbeddedAgent </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// PowerManager
c7 [label=<<table title="PowerManager" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> PowerManager </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// SetTopController
c8 [label=<<table title="SetTopController" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SetTopController </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> authorizationLevel </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> startUp() </td></tr><tr><td align="left" balign="left"> shutDown() </td></tr><tr><td align="left" balign="left"> connect() </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// ChannelIterator
c9 [label=<<table title="ChannelIterator" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ChannelIterator </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// URLStreamHandler
c10 [label=<<table title="URLStreamHandler" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> URLStreamHandler </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> OpenConnection() </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> parseURL() </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> setURL() </font></td></tr><tr><td align="left" balign="left"><font face="Helvetica-Oblique" point-size="10.0"> toExternalForm() </font></td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//SetTopController extends Controller
c5:p -> c8:p [dir=back,arrowtail=empty];
//SetTopController extends EmbeddedAgent
c6:p -> c8:p [dir=back,arrowtail=empty];
//SetTopController implements URLStreamHandler
c10:p -> c8:p [dir=back,arrowtail=empty,style=dashed];
// SetTopController NAVASSOC PowerManager
c8:p -> c7:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
// ChannelIterator DEPEND SetTopController
c9:p -> c8:p [taillabel="", label="&#171;friend&#187;", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open, style=dashed];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Controller
c5 [label=<<table title="Controller" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Controller </td></tr></table></td></tr></table>>];
// EmbeddedAgent
c6 [label=<<table title="EmbeddedAgent" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> EmbeddedAgent </td></tr></table></td></tr></table>>];
// PowerManager
c7 [label=<<table title="PowerManager" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> PowerManager </td></tr></table></td></tr></table>>];
// SetTopController
c8 [label=<<table title="SetTopController" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SetTopController </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> authorizationLevel </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> startUp() </td></tr><tr><td align="left" balign="left"> shutDown() </td></tr><tr><td align="left" balign="left"> connect() </td></tr></table></td></tr></table>>];
// ChannelIterator
c9 [label=<<table title="ChannelIterator" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ChannelIterator </td></tr></table></td></tr></table>>];
// URLStreamHandler
c10 [label=<<table title="URLStreamHandler" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> URLStreamHandler </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"><i> OpenConnection() </i></td></tr><tr><td align="left" balign="left"><i> parseURL() </i></td></tr><tr><td align="left" balign="left"><i> setURL() </i></td></tr><tr><td align="left" balign="left"><i> toExternalForm() </i></td></tr></table></td></tr></table>>];
// SetTopController extends Controller
c5 -> c8 [arrowtail=empty,dir=back,weight=10];
// SetTopController extends EmbeddedAgent
c6 -> c8 [arrowtail=empty,dir=back,weight=10];
// SetTopController implements URLStreamHandler
c10 -> c8 [arrowtail=empty,style=dashed,dir=back,weight=9];
// SetTopController navassoc PowerManager
c8 -> c7 [arrowhead=open,weight=1];
// ChannelIterator depend SetTopController
c9 -> c8 [arrowhead=open,style=dashed,weight=0,label="&#171;friend&#187;"];
}

View File

@ -5,20 +5,21 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
rankdir=LR;
// UserGroup
c12 [label=<<table title="UserGroup" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> UserGroup </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// User
c13 [label=<<table title="User" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> User </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Password
c14 [label=<<table title="Password" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Password </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// UserGroup ASSOC User
c12:p -> c13:p [taillabel="*", label="", headlabel="*\n\n+user ", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// User NAVASSOC Password
c13:p -> c14:p [taillabel="1\n\n+owner\r", label="", headlabel="*\n\n+key", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
rankdir=LR;
// UserGroup
c12 [label=<<table title="UserGroup" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> UserGroup </td></tr></table></td></tr></table>>];
// User
c13 [label=<<table title="User" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> User </td></tr></table></td></tr></table>>];
// Password
c14 [label=<<table title="Password" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Password </td></tr></table></td></tr></table>>];
// UserGroup assoc User
c12 -> c13 [arrowhead=none,weight=2,taillabel="*", headlabel="*\n\n+user "];
// User navassoc Password
c13 -> c14 [arrowhead=open,weight=1,taillabel="1\n\n+owner\r", headlabel="*\n\n+key"];
}

View File

@ -5,23 +5,24 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Tyre
c15 [label=<<table title="Tyre" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Tyre </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Engine
c16 [label=<<table title="Engine" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Engine </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Body
c17 [label=<<table title="Body" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Body </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Car
c18 [label=<<table title="Car" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Car </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Car COMPOSED Tyre
c18:p -> c15:p [taillabel="1", label="", headlabel="4", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
// Car COMPOSED Engine
c18:p -> c16:p [taillabel="1", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
// Car COMPOSED Body
c18:p -> c17:p [taillabel="1", label="", headlabel="1", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Tyre
c15 [label=<<table title="Tyre" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Tyre </td></tr></table></td></tr></table>>];
// Engine
c16 [label=<<table title="Engine" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Engine </td></tr></table></td></tr></table>>];
// Body
c17 [label=<<table title="Body" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Body </td></tr></table></td></tr></table>>];
// Car
c18 [label=<<table title="Car" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Car </td></tr></table></td></tr></table>>];
// Car composed Tyre
c18 -> c15 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1", headlabel="4"];
// Car composed Engine
c18 -> c16 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1", headlabel="1"];
// Car composed Body
c18 -> c17 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1", headlabel="1"];
}

View File

@ -5,53 +5,54 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// HttpResponseBase
c19 [label=<<table title="HttpResponseBase" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> HttpResponseBase </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// HttpResponseWrapper
c20 [label=<<table title="HttpResponseWrapper" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="Helvetica-Oblique"> HttpResponseWrapper </font></td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// HttpResponseFacade
c21 [label=<<table title="HttpResponseFacade" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> HttpResponseFacade </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// ResponseWrapper
c22 [label=<<table title="ResponseWrapper" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="Helvetica-Oblique"> ResponseWrapper </font></td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// HttpResponse
c23 [label=<<table title="HttpResponse" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> HttpResponse </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// ResponseBase
c24 [label=<<table title="ResponseBase" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><font face="Helvetica-Oblique"> ResponseBase </font></td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// HttpServletResponse
c25 [label=<<table title="HttpServletResponse" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> HttpServletResponse </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// ResponseFacade
c26 [label=<<table title="ResponseFacade" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ResponseFacade </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// ServletResponse
c27 [label=<<table title="ServletResponse" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> ServletResponse </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Response
c28 [label=<<table title="Response" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> Response </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//HttpResponseBase extends ResponseBase
c24:p -> c19:p [dir=back,arrowtail=empty];
//HttpResponseBase implements HttpResponse
c23:p -> c19:p [dir=back,arrowtail=empty,style=dashed];
//HttpResponseBase implements HttpServletResponse
c25:p -> c19:p [dir=back,arrowtail=empty,style=dashed];
//HttpResponseWrapper extends ResponseWrapper
c22:p -> c20:p [dir=back,arrowtail=empty];
//HttpResponseWrapper implements HttpResponse
c23:p -> c20:p [dir=back,arrowtail=empty,style=dashed];
//HttpResponseFacade extends ResponseFacade
c26:p -> c21:p [dir=back,arrowtail=empty];
//HttpResponseFacade implements HttpServletResponse
c25:p -> c21:p [dir=back,arrowtail=empty,style=dashed];
//ResponseWrapper implements Response
c28:p -> c22:p [dir=back,arrowtail=empty,style=dashed];
//HttpResponse implements Response
c28:p -> c23:p [dir=back,arrowtail=empty,style=dashed];
//ResponseBase implements Response
c28:p -> c24:p [dir=back,arrowtail=empty,style=dashed];
//ResponseBase implements ServletResponse
c27:p -> c24:p [dir=back,arrowtail=empty,style=dashed];
//ResponseFacade implements ServletResponse
c27:p -> c26:p [dir=back,arrowtail=empty,style=dashed];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// HttpResponseBase
c19 [label=<<table title="HttpResponseBase" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> HttpResponseBase </td></tr></table></td></tr></table>>];
// HttpResponseWrapper
c20 [label=<<table title="HttpResponseWrapper" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><i> HttpResponseWrapper </i></td></tr></table></td></tr></table>>];
// HttpResponseFacade
c21 [label=<<table title="HttpResponseFacade" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> HttpResponseFacade </td></tr></table></td></tr></table>>];
// ResponseWrapper
c22 [label=<<table title="ResponseWrapper" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><i> ResponseWrapper </i></td></tr></table></td></tr></table>>];
// HttpResponse
c23 [label=<<table title="HttpResponse" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> HttpResponse </td></tr></table></td></tr></table>>];
// ResponseBase
c24 [label=<<table title="ResponseBase" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"><i> ResponseBase </i></td></tr></table></td></tr></table>>];
// HttpServletResponse
c25 [label=<<table title="HttpServletResponse" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> HttpServletResponse </td></tr></table></td></tr></table>>];
// ResponseFacade
c26 [label=<<table title="ResponseFacade" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> ResponseFacade </td></tr></table></td></tr></table>>];
// ServletResponse
c27 [label=<<table title="ServletResponse" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> ServletResponse </td></tr></table></td></tr></table>>];
// Response
c28 [label=<<table title="Response" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;interface&#187; </td></tr><tr><td align="center" balign="center"> Response </td></tr></table></td></tr></table>>];
// HttpResponseBase extends ResponseBase
c24 -> c19 [arrowtail=empty,dir=back,weight=10];
// HttpResponseBase implements HttpResponse
c23 -> c19 [arrowtail=empty,style=dashed,dir=back,weight=9];
// HttpResponseBase implements HttpServletResponse
c25 -> c19 [arrowtail=empty,style=dashed,dir=back,weight=9];
// HttpResponseWrapper extends ResponseWrapper
c22 -> c20 [arrowtail=empty,dir=back,weight=10];
// HttpResponseWrapper implements HttpResponse
c23 -> c20 [arrowtail=empty,style=dashed,dir=back,weight=9];
// HttpResponseFacade extends ResponseFacade
c26 -> c21 [arrowtail=empty,dir=back,weight=10];
// HttpResponseFacade implements HttpServletResponse
c25 -> c21 [arrowtail=empty,style=dashed,dir=back,weight=9];
// ResponseWrapper implements Response
c28 -> c22 [arrowtail=empty,style=dashed,dir=back,weight=9];
// HttpResponse implements Response
c28 -> c23 [arrowtail=empty,style=dashed,dir=back,weight=9];
// ResponseBase implements Response
c28 -> c24 [arrowtail=empty,style=dashed,dir=back,weight=9];
// ResponseBase implements ServletResponse
c27 -> c24 [arrowtail=empty,style=dashed,dir=back,weight=9];
// ResponseFacade implements ServletResponse
c27 -> c26 [arrowtail=empty,style=dashed,dir=back,weight=9];
}

View File

@ -5,19 +5,20 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Person
c30 [label=<<table title="Person" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor=".13 .9 1"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Person </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Employee
c31 [label=<<table title="Employee" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor=".13 .9 1"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Employee </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Client
c32 [label=<<table title="Client" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor=".13 .9 1"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Client </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//Employee extends Person
c30:p -> c31:p [dir=back,arrowtail=empty];
//Client extends Person
c30:p -> c32:p [dir=back,arrowtail=empty];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Person
c30 [label=<<table title="Person" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor=".13 .9 1"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Person </td></tr></table></td></tr></table>>];
// Employee
c31 [label=<<table title="Employee" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor=".13 .9 1"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Employee </td></tr></table></td></tr></table>>];
// Client
c32 [label=<<table title="Client" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor=".13 .9 1"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Client </td></tr></table></td></tr></table>>];
// Employee extends Person
c30 -> c31 [arrowtail=empty,dir=back,weight=10];
// Client extends Person
c30 -> c32 [arrowtail=empty,dir=back,weight=10];
}

View File

@ -5,11 +5,12 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// ActionQueue
c35 [label=<<table title="ActionQueue" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;container&#187; </td></tr><tr><td align="center" balign="center"> ActionQueue </td></tr><tr><td align="right" balign="right"> {version = 3.2} </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> add(a : Action) </td></tr><tr><td align="left" balign="left"> add(a : Action, n : int) </td></tr><tr><td align="right" balign="right"> {version = 1.0} </td></tr><tr><td align="left" balign="left"> remove(n : int) </td></tr><tr><td align="left" balign="left"> &#171;query&#187; </td></tr><tr><td align="left" balign="left"> length() : int </td></tr><tr><td align="left" balign="left"> &#171;helper functions&#187; </td></tr><tr><td align="left" balign="left"> reorder() </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// ActionQueue
c35 [label=<<table title="ActionQueue" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;container&#187; </td></tr><tr><td align="center" balign="center"> ActionQueue </td></tr><tr><td align="right" balign="right"> {version = 3.2} </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> add(a : Action) </td></tr><tr><td align="left" balign="left"> add(a : Action, n : int) </td></tr><tr><td align="right" balign="right"> {version = 1.0} </td></tr><tr><td align="left" balign="left"> remove(n : int) </td></tr><tr><td align="left" balign="left"> &#171;query&#187; </td></tr><tr><td align="left" balign="left"> length() : int </td></tr><tr><td align="left" balign="left"> &#171;helper functions&#187; </td></tr><tr><td align="left" balign="left"> reorder() </td></tr></table></td></tr></table>>];
}

View File

@ -5,25 +5,26 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Serif",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
bgcolor=".7 .9 1";
// Pixel
c37 [label=<<table title="Pixel" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="#a0a0a0"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Pixel </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> - x : int </td></tr><tr><td align="left" balign="left"> - y : int </td></tr></table></td></tr></table>>, URL="null", fontname="arial", fontcolor="white", fontsize=14.0];
// Red
c38 [label=<<table title="Red" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="red"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Red </td></tr></table></td></tr></table>>, URL="null", fontname="Serif", fontcolor="black", fontsize=14.0];
// Green
c39 [label=<<table title="Green" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="green"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Green </td></tr></table></td></tr></table>>, URL="null", fontname="Serif", fontcolor="black", fontsize=14.0];
// Blue
c40 [label=<<table title="Blue" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p" bgcolor="blue"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Blue </td></tr></table></td></tr></table>>, URL="null", fontname="Serif", fontcolor="black", fontsize=14.0];
// Pixel COMPOSED Red
c37:p -> c38:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="yellow", arrowhead=none, arrowtail=diamond, dir=both];
// Pixel COMPOSED Green
c37:p -> c39:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="yellow", arrowhead=none, arrowtail=diamond, dir=both];
// Pixel COMPOSED Blue
c37:p -> c40:p [taillabel="", label="", headlabel="", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="yellow", arrowhead=none, arrowtail=diamond, dir=both];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="yellow"];
node [fontname="Serif",fontcolor="black",fontsize=14,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
bgcolor=".7 .9 1";
// Pixel
c37 [label=<<table title="Pixel" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="#a0a0a0"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Pixel </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> - x : int </td></tr><tr><td align="left" balign="left"> - y : int </td></tr></table></td></tr></table>>];
// Red
c38 [label=<<table title="Red" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="red"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Red </td></tr></table></td></tr></table>>];
// Green
c39 [label=<<table title="Green" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="green"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Green </td></tr></table></td></tr></table>>];
// Blue
c40 [label=<<table title="Blue" border="0" cellborder="1" cellspacing="0" cellpadding="2" bgcolor="blue"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Blue </td></tr></table></td></tr></table>>];
// Pixel composed Red
c37 -> c38 [arrowhead=none,arrowtail=diamond,dir=back,weight=6];
// Pixel composed Green
c37 -> c39 [arrowhead=none,arrowtail=diamond,dir=back,weight=6];
// Pixel composed Blue
c37 -> c40 [arrowhead=none,arrowtail=diamond,dir=back,weight=6];
}

View File

@ -5,11 +5,12 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Junk
c43 [label=<<table title="Junk" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Junk </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> - value : int </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> + Junk(val : int) </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Junk
c43 [label=<<table title="Junk" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Junk </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> - value : int </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> + Junk(val : int) </td></tr></table></td></tr></table>>];
}

View File

@ -5,15 +5,16 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Person1
c45 [label=<<table title="Person1" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Person1 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> ~ address : String </td></tr><tr><td align="left" balign="left"> ~ name : String </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Person2
c46 [label=<<table title="Person2" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Person2 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> ~ displayName() : String </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Person3
c47 [label=<<table title="Person3" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Person3 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> address : Address </td></tr><tr><td align="left" balign="left"> name : String </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> displayName() : String </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Person1
c45 [label=<<table title="Person1" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Person1 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> ~ address : String </td></tr><tr><td align="left" balign="left"> ~ name : String </td></tr></table></td></tr></table>>];
// Person2
c46 [label=<<table title="Person2" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Person2 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> ~ displayName() : String </td></tr></table></td></tr></table>>];
// Person3
c47 [label=<<table title="Person3" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Person3 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> address : Address </td></tr><tr><td align="left" balign="left"> name : String </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> displayName() : String </td></tr></table></td></tr></table>>];
}

View File

@ -5,13 +5,14 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Base
c48 [label=<<table title="Base" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Base </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Test2<B extends a.b.Base>
c49 [label=<<table title="Test2" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Test2&lt;B extends Base&gt; </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Base
c48 [label=<<table title="Base" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Base </td></tr></table></td></tr></table>>];
// Test2<B extends a.b.Base>
c49 [label=<<table title="Test2" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Test2&lt;B extends Base&gt; </td></tr></table></td></tr></table>>];
}

View File

@ -5,21 +5,22 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// a.b.c.UMLOptions
c50 [label=<<table title="a.b.c.UMLOptions" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> UMLOptions </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// a.b.c.UserGroup
c51 [label=<<table title="a.b.c.UserGroup" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> UserGroup </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// a.b.c.User
c52 [label=<<table title="a.b.c.User" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> User </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// a.b.c.Password
c53 [label=<<table title="a.b.c.Password" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Password </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// a.b.c.UserGroup ASSOC a.b.c.User
c51:p -> c52:p [taillabel="*", label="", headlabel="*\n\n+user ", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// a.b.c.User NAVASSOC a.b.c.Password
c52:p -> c53:p [taillabel="1\n\n+owner\r", label="", headlabel="*\n\n+key", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=open];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// a.b.c.UMLOptions
c50 [label=<<table title="a.b.c.UMLOptions" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> UMLOptions </td></tr></table></td></tr></table>>];
// a.b.c.UserGroup
c51 [label=<<table title="a.b.c.UserGroup" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> UserGroup </td></tr></table></td></tr></table>>];
// a.b.c.User
c52 [label=<<table title="a.b.c.User" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> User </td></tr></table></td></tr></table>>];
// a.b.c.Password
c53 [label=<<table title="a.b.c.Password" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Password </td></tr></table></td></tr></table>>];
// a.b.c.UserGroup assoc a.b.c.User
c51 -> c52 [arrowhead=none,weight=2,taillabel="*", headlabel="*\n\n+user "];
// a.b.c.User navassoc a.b.c.Password
c52 -> c53 [arrowhead=open,weight=1,taillabel="1\n\n+owner\r", headlabel="*\n\n+key"];
}

View File

@ -5,49 +5,50 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Asset
c55 [label=<<table title="Asset" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Asset </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// InterestBearingItem
c56 [label=<<table title="InterestBearingItem" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InterestBearingItem </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// InsurableItem
c57 [label=<<table title="InsurableItem" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InsurableItem </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// BankAccount
c58 [label=<<table title="BankAccount" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> BankAccount </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// RealEstate
c59 [label=<<table title="RealEstate" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> RealEstate </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Security
c60 [label=<<table title="Security" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Security </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Stock
c61 [label=<<table title="Stock" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Stock </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Bond
c62 [label=<<table title="Bond" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Bond </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// CheckingAccount
c63 [label=<<table title="CheckingAccount" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> CheckingAccount </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// SavingsAccount
c64 [label=<<table title="SavingsAccount" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SavingsAccount </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
//BankAccount extends Asset
c55:p -> c58:p [dir=back,arrowtail=empty];
//BankAccount extends InsurableItem
c57:p -> c58:p [dir=back,arrowtail=empty];
//BankAccount extends InterestBearingItem
c56:p -> c58:p [dir=back,arrowtail=empty];
//RealEstate extends Asset
c55:p -> c59:p [dir=back,arrowtail=empty];
//RealEstate extends InsurableItem
c57:p -> c59:p [dir=back,arrowtail=empty];
//Security extends Asset
c55:p -> c60:p [dir=back,arrowtail=empty];
//Stock extends Security
c60:p -> c61:p [dir=back,arrowtail=empty];
//Bond extends Security
c60:p -> c62:p [dir=back,arrowtail=empty];
//CheckingAccount extends BankAccount
c58:p -> c63:p [dir=back,arrowtail=empty];
//SavingsAccount extends BankAccount
c58:p -> c64:p [dir=back,arrowtail=empty];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Asset
c55 [label=<<table title="Asset" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Asset </td></tr></table></td></tr></table>>];
// InterestBearingItem
c56 [label=<<table title="InterestBearingItem" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InterestBearingItem </td></tr></table></td></tr></table>>];
// InsurableItem
c57 [label=<<table title="InsurableItem" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> InsurableItem </td></tr></table></td></tr></table>>];
// BankAccount
c58 [label=<<table title="BankAccount" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> BankAccount </td></tr></table></td></tr></table>>];
// RealEstate
c59 [label=<<table title="RealEstate" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> RealEstate </td></tr></table></td></tr></table>>];
// Security
c60 [label=<<table title="Security" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Security </td></tr></table></td></tr></table>>];
// Stock
c61 [label=<<table title="Stock" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Stock </td></tr></table></td></tr></table>>];
// Bond
c62 [label=<<table title="Bond" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Bond </td></tr></table></td></tr></table>>];
// CheckingAccount
c63 [label=<<table title="CheckingAccount" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> CheckingAccount </td></tr></table></td></tr></table>>];
// SavingsAccount
c64 [label=<<table title="SavingsAccount" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> SavingsAccount </td></tr></table></td></tr></table>>];
// BankAccount extends Asset
c55 -> c58 [arrowtail=empty,dir=back,weight=10];
// BankAccount extends InsurableItem
c57 -> c58 [arrowtail=empty,dir=back,weight=10];
// BankAccount extends InterestBearingItem
c56 -> c58 [arrowtail=empty,dir=back,weight=10];
// RealEstate extends Asset
c55 -> c59 [arrowtail=empty,dir=back,weight=10];
// RealEstate extends InsurableItem
c57 -> c59 [arrowtail=empty,dir=back,weight=10];
// Security extends Asset
c55 -> c60 [arrowtail=empty,dir=back,weight=10];
// Stock extends Security
c60 -> c61 [arrowtail=empty,dir=back,weight=10];
// Bond extends Security
c60 -> c62 [arrowtail=empty,dir=back,weight=10];
// CheckingAccount extends BankAccount
c58 -> c63 [arrowtail=empty,dir=back,weight=10];
// SavingsAccount extends BankAccount
c58 -> c64 [arrowtail=empty,dir=back,weight=10];
}

View File

@ -5,13 +5,14 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Java5
c78 [label=<<table title="Java5" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Java5 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> ~ state : Java5.States </td></tr><tr><td align="left" balign="left"> - specifiedPackages : Set&lt;String&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> + printAll(args : String[]) </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Java5.States
c79 [label=<<table title="Java5.States" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;enumeration&#187; </td></tr><tr><td align="center" balign="center"> States </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> start </td></tr><tr><td align="left" balign="left"> dash </td></tr><tr><td align="left" balign="left"> colon </td></tr><tr><td align="left" balign="left"> space </td></tr><tr><td align="left" balign="left"> open </td></tr><tr><td align="left" balign="left"> w </td></tr><tr><td align="left" balign="left"> close </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Java5
c78 [label=<<table title="Java5" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Java5 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> ~ state : Java5.States </td></tr><tr><td align="left" balign="left"> - specifiedPackages : Set&lt;String&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> + printAll(args : String[]) </td></tr></table></td></tr></table>>];
// Java5.States
c79 [label=<<table title="Java5.States" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;enumeration&#187; </td></tr><tr><td align="center" balign="center"> States </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> start </td></tr><tr><td align="left" balign="left"> dash </td></tr><tr><td align="left" balign="left"> colon </td></tr><tr><td align="left" balign="left"> space </td></tr><tr><td align="left" balign="left"> open </td></tr><tr><td align="left" balign="left"> w </td></tr><tr><td align="left" balign="left"> close </td></tr></table></td></tr></table>>];
}

View File

@ -5,33 +5,34 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// School
c103 [label=<<table title="School" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> School </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr><tr><td align="left" balign="left"> address : String </td></tr><tr><td align="left" balign="left"> phone : Number </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> addStudent() </td></tr><tr><td align="left" balign="left"> removeStudent() </td></tr><tr><td align="left" balign="left"> getStudent() </td></tr><tr><td align="left" balign="left"> getAllStudents() </td></tr><tr><td align="left" balign="left"> addDepartment() </td></tr><tr><td align="left" balign="left"> removeDepartment() </td></tr><tr><td align="left" balign="left"> getDepartment() </td></tr><tr><td align="left" balign="left"> getAllDepartments() </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Department
c104 [label=<<table title="Department" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Department </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> addInstructor() </td></tr><tr><td align="left" balign="left"> removeInstructor() </td></tr><tr><td align="left" balign="left"> getInstructor() </td></tr><tr><td align="left" balign="left"> getAllInstructors() </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Student
c105 [label=<<table title="Student" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Student </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr><tr><td align="left" balign="left"> studentID : Number </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Course
c106 [label=<<table title="Course" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Course </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr><tr><td align="left" balign="left"> courseID : Number </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Instructor
c107 [label=<<table title="Instructor" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Instructor </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// School HAS Student
c103:p -> c105:p [taillabel="1..*", label="Member", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=ediamond, dir=both];
// School COMPOSED Department
c103:p -> c104:p [taillabel="1..*", label="Has", headlabel="1..*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=diamond, dir=both];
// Department ASSOC Course
c104:p -> c106:p [taillabel="1..*", label="", headlabel="1..*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// Department ASSOC Instructor
c104:p -> c107:p [taillabel="0..*", label="", headlabel="0..1 chairperson", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// Department HAS Instructor
c104:p -> c107:p [taillabel="1..*", label="AssignedTo", headlabel="1..*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none, arrowtail=ediamond, dir=both];
// Student ASSOC Course
c105:p -> c106:p [taillabel="*", label="Attends", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
// Instructor ASSOC Course
c107:p -> c106:p [taillabel="1..*", label="Teaches", headlabel="*", fontname="Helvetica", fontcolor="black", fontsize=10.0, color="black", arrowhead=none];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// School
c103 [label=<<table title="School" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> School </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr><tr><td align="left" balign="left"> address : String </td></tr><tr><td align="left" balign="left"> phone : Number </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> addStudent() </td></tr><tr><td align="left" balign="left"> removeStudent() </td></tr><tr><td align="left" balign="left"> getStudent() </td></tr><tr><td align="left" balign="left"> getAllStudents() </td></tr><tr><td align="left" balign="left"> addDepartment() </td></tr><tr><td align="left" balign="left"> removeDepartment() </td></tr><tr><td align="left" balign="left"> getDepartment() </td></tr><tr><td align="left" balign="left"> getAllDepartments() </td></tr></table></td></tr></table>>];
// Department
c104 [label=<<table title="Department" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Department </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> addInstructor() </td></tr><tr><td align="left" balign="left"> removeInstructor() </td></tr><tr><td align="left" balign="left"> getInstructor() </td></tr><tr><td align="left" balign="left"> getAllInstructors() </td></tr></table></td></tr></table>>];
// Student
c105 [label=<<table title="Student" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Student </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr><tr><td align="left" balign="left"> studentID : Number </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// Course
c106 [label=<<table title="Course" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Course </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr><tr><td align="left" balign="left"> courseID : Number </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// Instructor
c107 [label=<<table title="Instructor" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Instructor </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> name : Name </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr></table>>];
// School has Student
c103 -> c105 [arrowhead=none,arrowtail=ediamond,dir=back,weight=4,taillabel="1..*", label="Member", headlabel="*"];
// School composed Department
c103 -> c104 [arrowhead=none,arrowtail=diamond,dir=back,weight=6,taillabel="1..*", label="Has", headlabel="1..*"];
// Department assoc Course
c104 -> c106 [arrowhead=none,weight=2,taillabel="1..*", headlabel="1..*"];
// Department assoc Instructor
c104 -> c107 [arrowhead=none,weight=2,taillabel="0..*", headlabel="0..1 chairperson"];
// Department has Instructor
c104 -> c107 [arrowhead=none,arrowtail=ediamond,dir=back,weight=4,taillabel="1..*", label="AssignedTo", headlabel="1..*"];
// Student assoc Course
c105 -> c106 [arrowhead=none,weight=2,taillabel="*", label="Attends", headlabel="*"];
// Instructor assoc Course
c107 -> c106 [arrowhead=none,weight=2,taillabel="1..*", label="Teaches", headlabel="*"];
}

View File

@ -5,13 +5,14 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Java5
c109 [label=<<table title="Java5" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Java5 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> ~ state : Java5.States </td></tr><tr><td align="left" balign="left"> + specifiedPackages : Set&lt;String&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> + printAll(args : String[]) </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
// Java5.States
c110 [label=<<table title="Java5.States" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;enumeration&#187; </td></tr><tr><td align="center" balign="center"> States </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> start </td></tr><tr><td align="left" balign="left"> dash </td></tr><tr><td align="left" balign="left"> colon </td></tr><tr><td align="left" balign="left"> space </td></tr><tr><td align="left" balign="left"> open </td></tr><tr><td align="left" balign="left"> w </td></tr><tr><td align="left" balign="left"> close </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Java5
c109 [label=<<table title="Java5" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Java5 </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> ~ state : Java5.States </td></tr><tr><td align="left" balign="left"> + specifiedPackages : Set&lt;String&gt; </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> + printAll(args : String[]) </td></tr></table></td></tr></table>>];
// Java5.States
c110 [label=<<table title="Java5.States" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> &#171;enumeration&#187; </td></tr><tr><td align="center" balign="center"> States </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> start </td></tr><tr><td align="left" balign="left"> dash </td></tr><tr><td align="left" balign="left"> colon </td></tr><tr><td align="left" balign="left"> space </td></tr><tr><td align="left" balign="left"> open </td></tr><tr><td align="left" balign="left"> w </td></tr><tr><td align="left" balign="left"> close </td></tr></table></td></tr></table>>];
}

View File

@ -5,11 +5,12 @@
#
digraph G {
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10];
node [fontname="Helvetica",fontsize=10,shape=plaintext];
nodesep=0.25;
ranksep=0.5;
// Toolbar
c120 [label=<<table title="Toolbar" border="0" cellborder="1" cellspacing="0" cellpadding="2" port="p"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Toolbar </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> # currentSelection : Tool </td></tr><tr><td align="left" balign="left"> # toolCount : Integer </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> + pickItem(i : Integer) </td></tr><tr><td align="left" balign="left"> + addTool(t : Tool) </td></tr><tr><td align="left" balign="left"> + removeTool(i : Integer) </td></tr><tr><td align="left" balign="left"> + getTool() : Tool </td></tr><tr><td align="left" balign="left"> # checkOrphans() </td></tr><tr><td align="left" balign="left"> - compact() </td></tr></table></td></tr></table>>, URL="null", fontname="Helvetica", fontcolor="black", fontsize=10.0];
graph [fontnames="svg"]
edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10,color="black"];
node [fontname="Helvetica",fontcolor="black",fontsize=10,shape=plaintext,margin=0,width=0,height=0];
nodesep=0.25;
ranksep=0.5;
// Toolbar
c120 [label=<<table title="Toolbar" border="0" cellborder="1" cellspacing="0" cellpadding="2"><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="center" balign="center"> Toolbar </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> # currentSelection : Tool </td></tr><tr><td align="left" balign="left"> # toolCount : Integer </td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="1"><tr><td align="left" balign="left"> + pickItem(i : Integer) </td></tr><tr><td align="left" balign="left"> + addTool(t : Tool) </td></tr><tr><td align="left" balign="left"> + removeTool(i : Integer) </td></tr><tr><td align="left" balign="left"> + getTool() : Tool </td></tr><tr><td align="left" balign="left"> # checkOrphans() </td></tr><tr><td align="left" balign="left"> - compact() </td></tr></table></td></tr></table>>];
}

13
testdata/java/active.java vendored Normal file
View File

@ -0,0 +1,13 @@
/**
* Active classes
*
* @opt operations
* @opt shape activeclass
* @hidden
*/
class UMLOptions {}
class Active {
protected int hidden;
public void run() {};
}

View File

@ -1,3 +1,2 @@
class Base {}
class Test2<B extends a.b.Base> {}
class Test2<B extends Base> {}

Some files were not shown because too many files have changed in this diff Show More