所以,我正在制作一个程序,它采用类图,并使用 JavaPoet 将其转换为 Java 代码。
类 Diagram 不是用 UML 编写的,它已经在程序内部用 java 建模。
这是给我带来问题的代码部分:(解析类中的所有属性,将它们添加到新的源代码中,如果缺少则添加 Setters/Getters)
for (Attribute a : classe.attributes) { //Parse all the attribute inside the class
TypeName aClass = stringToType(a.getType()); //the attribute tipe
FieldSpec aField = FieldSpec.builder(aClass, a.getName()) //the attribute
.addModifiers(javax.lang.model.element.Modifier.valueOf(a.getProtection().toUpperCase()), a.isStatic() ? Modifier.STATIC : null)
.build();
fields.add(aField);
MethodSpec aMethod = MethodSpec.methodBuilder("set" + upperFirst(a.getName()))
.addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)
.returns(TypeName.VOID)
.addParameter(aClass, a.getName())
.addStatement("this." + a.getName() + " = " + a.getName())
.build();
if (!methods.contains(aMethod)) //if not present, add the set method
methods.add(aMethod);
MethodSpec bMethod = MethodSpec.methodBuilder("get" + upperFirst(a.getName()))
.addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)
.addStatement("return " + a.getName())
.returns(aClass)
.build();
if (!methods.contains(bMethod)) methods.add(bMethod); //if not present, add the get method
}
我在最后一行得到以下异常:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at java.util.EnumSet.typeCheck(EnumSet.java:396)
at java.util.RegularEnumSet.add(RegularEnumSet.java:161)
at java.util.RegularEnumSet.add(RegularEnumSet.java:36)
at java.util.EnumSet.copyOf(EnumSet.java:179)
at com.squareup.javapoet.CodeWriter.emitModifiers(CodeWriter.java:172)
at com.squareup.javapoet.MethodSpec.emit(MethodSpec.java:86)
at com.squareup.javapoet.MethodSpec.toString(MethodSpec.java:164)
at com.squareup.javapoet.MethodSpec.equals(MethodSpec.java:153)
at java.util.ArrayList.indexOf(ArrayList.java:317)
at java.util.ArrayList.contains(ArrayList.java:300)
这是我发布的代码->
at base.controller.commands.ExportModelCommand.execute(ExportModelCommand.java:224)
at base.Main.executeCommand(Main.java:113)
at base.controller.menu.menuitem.ItemExport.lambda$new$0(ItemExport.java:17)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$343(ContextMenuContent.java:1358)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
我真的不明白为什么。
我尝试调试,在 NULL 处找不到任何东西。我如何找到问题?
完整代码 - 类模型(省略的部分是 getters/setters)
public class ClassModel {
private String name = "";
private String parent = null;
public ArrayList<Attribute> attributes = new ArrayList<Attribute>();
public ArrayList<Method> methods = new ArrayList<Method>();
public boolean isInterface;
private boolean isFinal;
private ProtectionLevel prote;
private String genericText="";
private String stereotype="";
public ClassModel() {
}
public ClassModel(ClassModel original) {
this.name = original.name;
this.parent = original.parent;
this.isInterface = original.isInterface;
/*
for (Map.Entry<String, Relation> e : original.relations.entrySet()) {
this.relations.put(e.getKey(), new Relation(e.getValue()));
}
*/
for (Attribute a : original.attributes) {
this.attributes.add(new Attribute(a));
}
for (Method m : original.methods) {
this.methods.add(new Method(m));
}
}
完整代码 - 导出命令:
public Message execute() {
///////////////////
/* Save As */
///////////////////
// Set tab flag to saved and remove '*' from tab name
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("./"));
chooser.setDialogTitle("Choose your folder");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
for (Tab tab : Main.project.getTabContainer().getTabs()) {
BaseDiagramModel currentModel = ((UMLTab) tab).getModel();
if (currentModel.getDiagramPosition() == 2) {
for (UMLElement e : currentModel) {
if (e instanceof UMLClassElementImage) {
//prepare content for new file java
ClassModel classe = ((UMLClassElementImage) e).modelClass;
ArrayList<MethodSpec> methods = new ArrayList<MethodSpec>();
ArrayList<FieldSpec> fields = new ArrayList<FieldSpec>();
ArrayList<UMLElement> composition = new ArrayList<UMLElement>();
ArrayList<UMLElement> aggregation = new ArrayList<UMLElement>();
ArrayList<UMLElement> inheritance = new ArrayList<UMLElement>();
for (UMLElement x : ((UMLNode<UMLElement>) e).getChildren()) {
if (x instanceof UMLArrowAggregation) {
aggregation.add(x);
} else if (x instanceof UMLArrowComposition) {
composition.add(x);
} else if (x instanceof UMLArrowEreditarieta) {
inheritance.add(x);
}
//else if (x instanceof UMLArrowDashedLineWithCentralLabelAndApexOnHead) {
// implementation.add(x);
//}
}
for (UMLElement aggregated : aggregation) {
UMLElement whatIsAfterTheArrow = ((UMLNode<UMLElement>) aggregated).getChildren().get(0);
ClassModel classeAgg = ((UMLClassElementImage) whatIsAfterTheArrow).modelClass;
FieldSpec aField = FieldSpec.builder(ClassName.get("", classeAgg.getName()), classeAgg.getName())
.addModifiers(Modifier.PROTECTED)
.build();
fields.add(aField);
MethodSpec aMethod = MethodSpec.methodBuilder("set" + upperFirst(classeAgg.getName()))
.addModifiers(Modifier.PUBLIC)
.returns(TypeName.VOID)
.addParameter(ClassName.get("", classeAgg.getName()), classeAgg.getName())
.addStatement("this." + classeAgg.getName() + " = " + classeAgg.getName())
.build();
if (!methods.contains(aMethod)) methods.add(aMethod);
MethodSpec bMethod = MethodSpec.methodBuilder("get" + upperFirst(classeAgg.getName()))
.addModifiers(Modifier.PUBLIC)
.addStatement("return " + classeAgg.getName())
.returns(ClassName.get("", classeAgg.getName()))
.build();
if (!methods.contains(bMethod)) methods.add(bMethod);
}
for (UMLElement composed : composition) {
UMLElement whatIsAfterTheArrow = ((UMLNode<UMLElement>) composed).getChildren().get(0);
ClassModel classeComp = ((UMLClassElementImage) whatIsAfterTheArrow).modelClass;
FieldSpec aField = FieldSpec.builder(ClassName.get("", classeComp.getName()), classeComp.getName())
.addModifiers(Modifier.PROTECTED, Modifier.FINAL)
.build();
fields.add(aField);
MethodSpec aMethod = MethodSpec.methodBuilder("set" + upperFirst(classeComp.getName()))
.addModifiers(Modifier.PUBLIC)
.returns(TypeName.VOID)
.addParameter(ClassName.get("", classeComp.getName()), classeComp.getName())
.addStatement("this." + classeComp.getName() + " = " + classeComp.getName())
.build();
if (!methods.contains(aMethod)) methods.add(aMethod);
MethodSpec bMethod = MethodSpec.methodBuilder("get" + upperFirst(classeComp.getName()))
.addModifiers(Modifier.PUBLIC)
.addStatement("return " + classeComp.getName())
.returns(ClassName.get("", classeComp.getName()))
.build();
if (!methods.contains(bMethod)) methods.add(bMethod);
}
for (Attribute a : classe.attributes) {
TypeName aClass = stringToType(a.getType());
FieldSpec aField = FieldSpec.builder(aClass, a.getName())
.addModifiers(javax.lang.model.element.Modifier.valueOf(a.getProtection().toUpperCase()), a.isStatic() ? Modifier.STATIC : null)
.build();
fields.add(aField);
MethodSpec aMethod = MethodSpec.methodBuilder("set" + upperFirst(a.getName()))
.addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)
.returns(TypeName.VOID)
.addParameter(aClass, a.getName())
.addStatement("this." + a.getName() + " = " + a.getName())
.build();
if (!methods.contains(aMethod))
methods.add(aMethod);
MethodSpec bMethod = MethodSpec.methodBuilder("get" + upperFirst(a.getName()))
.addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)
.addStatement("return " + a.getName())
.returns(aClass)
.build();
if (!methods.contains(bMethod)) methods.add(bMethod);
}
for (Method m : classe.methods) {
ArrayList<ParameterSpec> parametriSpec = new ArrayList<>();
Set<Attribute> parametri = m.getParameters();
for (Attribute singleParam : parametri) {
TypeName attClass = stringToType(singleParam.getType());
ParameterSpec test = ParameterSpec.builder(attClass, singleParam.getName())
// .addModifiers(Modifier.FINAL)
.build();
parametriSpec.add(test);
}
TypeName aClass = stringToType(m.getReturnType());
MethodSpec aMethod = MethodSpec.methodBuilder(m.getName())
.addModifiers(javax.lang.model.element.Modifier.valueOf(m.getProtection().toUpperCase()), m.isStatic() ? Modifier.STATIC : null)
.returns(aClass)
.addParameters(parametriSpec)
.build();
methods.add(aMethod);
}
TypeSpec theClass = null;
TypeName father = null;
if (!inheritance.isEmpty())
father = ClassName.get("", ((UMLClassElementImage) ((UMLNode<UMLElement>) inheritance.get(0)).getChildren().get(0)).modelClass.getName());
try {
theClass = TypeSpec.classBuilder(classe.getName())
.addModifiers(((UMLClassElementImage) e).modelClass.getFinal() ? new Modifier[] { javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase()), Modifier.FINAL} : new Modifier[] { javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase()) })
.addModifiers(javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase()), Modifier.FINAL)
.superclass(father == null ? ClassName.OBJECT : father)
.addMethods(methods)
.addFields(fields)
.build();
// Create object to choose and create new file
} catch (Exception exc) {
getFailureMessage("Il nome della classe potrebbe essere sbagliato?");
}
try {
JavaFile javaFile = JavaFile.builder(currentModel.getTitle(), theClass)
.build();
Path javaPath = Paths.get(chooser.getSelectedFile().getPath());
javaFile.writeTo(javaPath);
} catch (Exception exc) {
exc.printStackTrace();
return getFailureMessage();
}
}
//Else is not a class
}
}
}
else if (chooser.showOpenDialog(null) == JFileChooser.CANCEL_OPTION)
return getFailureMessage("Esportazione annullata");
// Save jsonArray into a file
// JsonFileManager jsonFileManager = new JsonFileManager();
// jsonFileManager.save(jsonArray, Main.project.getName() + ".citro");
return getSuccessMessage();
}