How to use Degraph to graph only models - java

I want to generate relationship graph among model classes using degraph.
Here is a representative example model, a POJO TaskEntryImpl that relates to Task:
package com.packag.tm.model.pojo;
public class TaskEntryImpl implements TaskEntry,Serializable {
private Integer id;
private Task task;
public Task getTask() {
return this.task;
}
public void setTask(Task v) {
this.task = v;
}
Packages containing models have model.pojo as part of the package name:
com.somepackage.events.model.pojo.DurationImpl
au.com.anotherpackage.ecrm.model.pojo.PayphoneImpl
How do I get a graph of models that meet the abovementioned characteristics?
For the curious: I wish I could have an Entity-Relation diagram instead.
These model classes are wired by Hibernate ORM. The original developers maintained SQL independent of the codebase and have never used foreign keys. So this rules out getting an entity-relation diagram from the database schema.

Create a file pojo.config with the following content
output = pojo.graphml
classpath = yourlib.jar
include = **.model.pojo.**
For getting started I'd put the file straight in the bin directory of Degraph.
The classpath value must point to the byte code you want to analyze, so either a jar-file or the directory, which contains all the class-files.
Now run (again from the bin directory):
degraph -f pojo.config
Degraph should print out the number of classes found and create a file pojo.graphml in the current directory (i.e. bin). You can open that with yed.
See the documentation of Degraph for how to create a useful layout with yed.
Note that Degraph will create boxes for the packages and put the boxes for classes into these package boxes. You can open the package boxes and then delete the package boxes, if you don't like them.

Related

Swagger Codegen how to reuse generated models?

I'm wondering if there is a way to properly generate models so that the generated models can reference each other?
I have a file structure like this
# Project Structure
/common
- Name.json
/v1
- User.json
/v2
- User.json
My Open API Specification files, both v1 and v2 reference common's Name properly
However the generated code ends up like this:
import v1.Name //created another Name class in v1 package
public class User {
Name name;
//...
}
import v2.Name //created another Name class in v2 package
public class User {
Name name;
//...
}
Ideally I would like to have the generated classes to look something like this
package v1
import common.Name
public class User {
Name name;
}
I have tried the import mappings and type mappings flags but the code generator cannot seem to find the common.Name class during creation of User class.
Any workarounds for this or is this a known limitation of the generator?
Edit: Ah it seems like impossible to have different generated packages in a single generation. So I must break these packages into their projects with their own types then utilize .openapi-ignore or looking at the jar depdendencies that's generated. Darn.

Create a maven archetype to generate multiple classes from one class template

I created a custom maven archetype that has a ClassName.java class that contains a property ${propertyName} with its getter and setter.
package ${package};
// Start of user code (import)
// End of user code (import)
/**
* Block ${BlockName}
*/
public class ${BlockName} extends Block<${BlockName}DTO> {
/**
* Item ${itemName}
*/
private final Item<${itemType}> ${itemName} = new Item.Control<${itemType}>(this, "${itemName}") {
};
// Getter and Setter
}
What I want to achieve when creating a new project from this custom archetype is giving multiple class names (for example: Car, Bicycle ...), and give also multiple properties for each class (for example: Car.door, Car.window, Bicycle.wheel ...), and have as output the classes created from the template ClassName.java as Car.java and Bicycle.java, but in each class have the ${itemName}, getters and setters replaced with the properties given.
You can probably code a groovy script for that and run it post-generation
Is there a way to post-process project generated from archetype?
On the other hand: Generating getters/setters is standard IDE functionality (e.g. easily done in Eclipse), so I am not sure whether this is really useful in an archetype.

How to copy packages in IntelliJ without creating numerous fully-specified links to the old package

To readers who like this question: I asked this question eight years ago (as of 2022) and there are only three upvotes. Please be aware that there are not many of us who need this feature and it is unlikely this will be supported by IntelliJ (or any modern IDE) for the foreseeable future.
When I use IntelliJ to copy a package which contains subpackages, every internal references to other classes in the same package is converted to an ugly fully-qualified name. Worse yet, this fully-qualified name links back to the old package instead of to the copied class in the new package! Does anyone know a workaround for this problem?
To reproduce this problem, I create a project structure like this:
Where A.java is:
package example;
public class A { }
And B. java is:
package example;
public class B {
private A a;
public B(A a) {
this.a = a;
}
}
I then Ctrl-C and Ctrl-V the example folder, and edit the dialog as below:
The copied version of classB now has every instance of A replaced with example.A
package example2;
import example.*;
public class B {
private example.A a;
public B(example.A a) {
this.a = a;
}
}
Does anyone have a suggested work-around to avoid this behavior, and simple change the package name, leaving everything else alone? Thanks!
P.S. While version control is usually the best way to track different versions of a program, I want to create an actual copy in this case. I use IntelliJ for teaching programming, and I create multiple versions of small, multi-packaged programs demonstrating how the program improves as I model refactoring techniques.
[Reported on Jet Brains here] 3.
You can try this:
Select class A and class B in the Project Structure;
Press F5;
In opened window enter new path, for example, C:\projects\other\src\example2;
Click Ok.
My latest workaround:
Set up IntelliJ to show excluded packages
Exclude the package to be copied (e.g. example)
Rename the package to be copied to a temporary name (e.g. example_temp). Ignore the warning about names not being updated.
Copy the package into the src folder. Rename it to the original name (e.g. example) during the copy. Since the original name is no longer excluded, the package will reappear.
Rename the copy to the new name. (e.g. rename example to example_v2)
Rename the temporary file back to the original (e.g. rename example_temp to example)
Remove the exclusion on the original directory (e.g. right-click example_temp->Mark directory as->Cancel Exclusion.)
Nothing of these were helpful for me, but I found a 100% working method. I had a structure like this:
package hometask1,
package hometask2,
package hometaskN,
where each next package has the previous package's classes as a base and has some new features with some classes changed. When I copied the previous package hometask(N-1) to the next hometaskN, it would have the previous package's (hometask(N-1)) import statements. I found that I have solved my problem following these steps:
Add new (temporary) project.
Create package with name equals previous package (for example, hometask1).
Copy classes from old project hometask1 to temp project hometask1.
Create package with necessary name in temporary project (for example, hometask2).
Move (not copy) all included packages and classes from temp hometask1 to temp hometask2. All imports are correct now.
Create in old project package with same name (hometask2).
Move or copy classes from temp hometask2 to main project hometask2.
Done.
Try copy/paste using the mouse. This method is slow but works.
1. Open the dir. you want to copy from.
2. Click on the class you want to copy.
3. Copy it.
4. In the new package, click on the dir where you need to put the class.
5. Click paste.
You may also need to update the imports to reflect the new dir.
Here is an effortless way (which works for sub packages that are in the same project or in different projects). Suppose we want to copy from Project1 to Project2 and we have the following structure (i.e. we want to copy the Car and Main classes in SubPackage21):
Project1
Package1
SubPackage11
Car.java
Main.java
Project2
Package2
SubPackage21
Step 1
Right-click on SubPackage21, click "Show in Explorer", and copy the path. It will be something like "...\Package2".
Step 2
Click on SubPackage11, press F5, paste the path and press "Enter".
You will get the following:
Project2
Package2
SubPackage21
SubPackage11
Car.java
Main.java
Step 3
Drag and drop the classes from SubPackage11 to SubPackage21, and press "Refactor" for all of them (this way the package name is replaced with the correct one, and no strange imports are added).

How do I get all the class names and method names of a project?

I have downloaded a huge project written in Java. I wish to know the Classes and Methods of every class that are available in the project (for further analysis). How can I recover this information. Can I try javadoc in eclipse?
I guess you may ask about changing SVN properties.
Follow this step if that so.
press Alt + Shift + Q
Select Show view (view : Outline)
then under that u can see all details
I have wrote a custom doclet to list the classname and its methods:
public class ListClassAndMethods {
public static boolean start(RootDoc root) {
ClassDoc[] classes = root.classes();
for(ClassDoc clazz : classes){
System.out.println("Class Name: "+clazz);
System.out.println("--------------------------");
for(MethodDoc methodz :clazz.methods()){
System.out.println(methodz.name());
}
}
return true;
}
}
you need to run create a jar of this class and refer it while creating
a javadoc using Eclipse IDE
I would extract all the class source files (.java) with find (if you're on a *nix implementation) and create an empty NetBeans project with just one package and all the classess inside it. Netbeans will correct the package declaration and you can easily use autogenerate javadoc to get a navigable web archive listing all the classes and public/protected methods.
Of course the code may not run anymore but you'll get what you want in minutes.

GWT: How to share a java Object (ie: EventBus) between two modules

I’m building a large application and I would like to split it in several modules like Core Module for initialization, users management, etc…, Customer Module, Production Module, etc…
I want to split it in multiples GWT modules (not using GWT splitting technique) and share an EventBus for broadcast some events like LoginEvent, LogoutEvent. I don’t want uses the code splitting technique because I want reduce the compile time and re-compile only the module that I modified.
This allow also to enable or disable a module by commenting the script tag in the HTML host page.
I’ve write the following code with using JSNI:
CoreModule’s EntryPoint:
private static SimpleEventBus eventBus = null;
public void onModuleLoad() {
export();
getEventBus().addHandler(MyEvent.TYPE, new MyEventHandler() {
#Override
public void onEvent(MyEvent myEvent) {
Window.alert(myEvent.getMessage());
}
});
}
public static SimpleEventBus getEventBus() {
if (eventBus == null)
eventBus = new SimpleEventBus();
return eventBus;
}
public static native void export() /*-{
$wnd.getEventBus = $entry(#testExporter.client.TestExporter::getEventBus());
}-*/;
CustomerModule’s EntryPoint:
public void onModuleLoad() {
Button button = new Button("Click me");
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
getEventBus().fireEvent(new MyEvent("Button clicked !"));
}
});
RootPanel.get().add(button);
}
public static native SimpleEventBus getEventBus() /*-{
// Create a useless eventBus because the GWT compiler make a call to a null instance
var eventBus = #com.google.gwt.event.shared.SimpleEventBus::new()();
eventBus = $wnd.getEventBus();
return eventBus;
}-*/;
But I’ve the following exception in Firebug when executing in the browser:
uncaugth exception [object Object]
I copied also the MyEvent and MyEventHandler classes that implements/interfaces a customer event.
P.S.: I know also the technique that consist to comment the other modules references to avoid to compile it.
A simpler answer is to not use multiple entry points.
==========================================
If what you are trying to achieve is breaking you code into manageable units but want to use all of them in the same page, you can:
create an "Application.gwt.xml" module with an entry point (equivalent to your initialization module, if I understand correctly)
create "UserManagement.gwt.xml" module without an entry point class
create other XXX modules without entry points
To create a module without entry point just remove the
<entry-point class='xxx'/>
from your gwt.xml files except for the "Application" one
You then need to include these modules into the "Application" module using
<inherits name="com.yourpackage.Module1Name" />
<inherits name="com.yourpackage.Module2Name" />
You then need to compile all of them together in one GWT build for module "com.yourpackage.Application".
When you do that make sure that both the compiled *.class and the source .java files for all your modules are available on the classpath.
Your "Application" entry point just needs to initialize and use the objects from the other modules
You cannot share code between different GWT compiled modules, unless you make some parts of your code available via jsni and call these exported methods via jsni, like you are trying in your query.
But be aware that: first, shared classes would be incompatible because each compilation would rename the classes/methods in a different way, and second, each compilation would remove different dead code pieces.
So in your case the SimpleEventBus returned in your window.getEventBus exported method is not known in other modules, although the other modules are using SimpleEventBus as well
The easiest way to do what you want, is to use GWT-exporter. First select correctly the js-api you want to export in each module, how you want to name it, and implement Exportable and annotate methods conveniently. Second take in account which objects would you use for the communication, because some of then could be incompatible. I would use primitive types, javascript object, and functions which are supported in GWT-exporter
I think that with GWT-exporter, for shared classes, if you annotate them in the same namespace and you export the same methods, hopefully you could use then in all modules but I'm not sure.
So export a js API via jsni or gwt-exporter and transfer pure primitive or js objects between them.
You can use the Frames and setup communication between the modules via WebMessage protocol. It will help only if the modules in one page and modules in separated war.

Categories