Skip to content
Snippets Groups Projects
Commit 8098b81c authored by Johannes Mey's avatar Johannes Mey
Browse files

improve generation of relation interface

parent 3a5bbb8e
No related branches found
No related tags found
1 merge request!13Better api generation
...@@ -170,10 +170,14 @@ aspect ComponentAnalysis { ...@@ -170,10 +170,14 @@ aspect ComponentAnalysis {
//--- isList --- //--- isList ---
syn boolean Component.isList() = false; syn boolean Component.isList() = false;
eq ListComponent.isList() = true; eq ListComponent.isList() = true;
eq NTAListComponent.isList() = true;
eq ManyRelationComponent.isList() = true;
//--- isOpt --- //--- isOpt ---
syn boolean Component.isOpt() = false; syn boolean Component.isOpt() = false;
eq OptComponent.isOpt() = true; eq OptComponent.isOpt() = true;
eq NTAOptComponent.isOpt() = true;
eq OptionalRelationComponent.isOpt() = true;
//--- isNullable --- //--- isNullable ---
syn boolean Component.isNullable() = false; syn boolean Component.isNullable() = false;
...@@ -248,10 +252,6 @@ aspect Constructors { ...@@ -248,10 +252,6 @@ aspect Constructors {
aspect Utils { aspect Utils {
//--- isMany ---
syn boolean RelationComponent.isMany() = false;
eq ManyRelationComponent.isMany() = true;
//--- toString --- //--- toString ---
public String SimpleTypeUse.toString() { public String SimpleTypeUse.toString() {
return getID(); return getID();
......
aspect BackendAPI { aspect BackendAPI {
public void Relation.generateAPI(StringBuilder sb) { public void Relation.generateAPI(StringBuilder sb) {
sb.append(ind(1) + "// " + prettyPrint() + "\n"); sb.append(ind(1) + "// api for " + prettyPrint() + "\n");
getDirection().generateAPI(sb); if (getLeft().isNavigable()) {
sb.append(ind(1) + "// left direction for " + prettyPrint() + "\n");
getLeft().generateAPI(sb);
}
if (getRight().isNavigable()) {
sb.append(ind(1) + "// right direction for " + prettyPrint() + "\n");
getRight().generateAPI(sb);
}
sb.append("\n"); sb.append("\n");
} }
public abstract void Direction.generateAPI(StringBuilder sb);
public void RelationComponent.generateAPI(StringBuilder sb) {
if (otherSide().isNavigable()) {
if (multiplicityOne() || multiplicityOpt()) {
if (otherSide().multiplicityOne() || otherSide().multiplicityOpt()) {
generateBiOneOne(sb);
} else if (otherSide().multiplicityMany()) {
generateBiOneMany(sb);
}
} else if (multiplicityMany()) {
if (otherSide().multiplicityOne() || otherSide().multiplicityOpt()) {
generateBiManyOne(sb);
} else if (otherSide().multiplicityMany()) {
generateBiManyMany(sb);
}
}
} else {
if (multiplicityOne() || multiplicityOpt()) {
generateDirectedZeroOneAPI(sb);
} else if (multiplicityMany()) {
generateDirectedManyAPI(sb);
}
}
}
public void RelationComponent.generateExtraOptAPI(StringBuilder sb) {
// has
sb.append(ind(1) + "public boolean " + getTypeUse().decl());
sb.append(".has" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "return ");
if (useJastAddNames) {
sb.append("get" + nameCapitalized());
} else {
sb.append(name());
}
sb.append("() != null;\n");
sb.append(ind(1) + "}\n");
// clear
sb.append(ind(1) + "public void " + getTypeUse().decl());
sb.append(".clear" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n");
sb.append(ind(1) + "}\n");
}
inh Relation Direction.relation(); inh Relation Direction.relation();
inh Relation RelationComponent.relation();
eq Relation.getChild().relation() = this; eq Relation.getChild().relation() = this;
eq Program.getChild().relation() = null; eq Program.getChild().relation() = null;
inh boolean RelationComponent.isNavigable();
eq Relation.getLeft().isNavigable() = getDirection().isNavigableLeftToRight();
eq Relation.getRight().isNavigable() = getDirection().isNavigableRightToLeft();
syn boolean Direction.isNavigableRightToLeft() = true;
eq RightDirection.isNavigableRightToLeft() = false;
syn boolean Direction.isNavigableLeftToRight() = true;
eq LeftDirection.isNavigableLeftToRight() = false;
public String RelationComponent.nameCapitalized() { public String RelationComponent.nameCapitalized() {
return name().substring(0,1).toUpperCase() + name().substring(1); return name().substring(0,1).toUpperCase() + name().substring(1);
} }
......
aspect BackendBidirectionalAPI { aspect BackendBidirectionalAPI {
public void Bidirectional.generateAPI(StringBuilder sb) {
RelationComponent l = relation().getLeft();
RelationComponent r = relation().getRight();
if (l.multiplicityOne()) { public void RelationComponent.generateBiOneOne(StringBuilder sb) {
if (r.multiplicityOne()) {
l.generateBiOneOne(sb, false);
r.generateBiOneOne(sb, false);
} else if (r.multiplicityOpt()) {
l.generateBiOneOne(sb, false);
r.generateBiOneOne(sb, true);
} else if (r.multiplicityMany()) {
l.generateBiOneMany(sb, false);
r.generateBiManyOne(sb, l);
}
} else if (l.multiplicityOpt()) {
if (r.multiplicityOne()) {
l.generateBiOneOne(sb, true);
r.generateBiOneOne(sb, false);
} else if (r.multiplicityOpt()) {
l.generateBiOneOne(sb, true);
r.generateBiOneOne(sb, true);
} else if (r.multiplicityMany()) {
l.generateBiOneMany(sb, true);
r.generateBiManyOne(sb, l);
}
} else if (l.multiplicityMany()) {
if (r.multiplicityOne()) {
l.generateBiManyOne(sb, r);
r.generateBiOneMany(sb, false);
} else if (r.multiplicityOpt()) {
l.generateBiManyOne(sb, r);
r.generateBiOneMany(sb, true);
} else if (r.multiplicityMany()) {
l.generateBiManyMany(sb, r);
r.generateBiManyMany(sb, l);
}
}
}
public void RelationComponent.generateBiOneOne(StringBuilder sb, boolean isOpt) {
// Get // Get
generateGetOne(sb); generateGetOne(sb);
// Set // Set
sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl()); sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl());
sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
if (!isOpt) { if (!isOpt()) {
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
} }
// unset the old opposite // unset the old opposite
...@@ -63,7 +24,7 @@ aspect BackendBidirectionalAPI { ...@@ -63,7 +24,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n");
if (resolverHelper | serializer) { if (resolverHelper | serializer) {
sb.append(ind(2) + "if (o == null || !o.is$Unresolved()) {\n"); sb.append(ind(2) + "if (o == null || !o.is$Unresolved()) {\n");
if (isOpt) { if (isOpt()) {
sb.append(ind(3) + "if (o != null) {\n"); sb.append(ind(3) + "if (o != null) {\n");
sb.append(ind(4) + "o.set" + otherSide().getImplAttributeName() + "(this);\n"); sb.append(ind(4) + "o.set" + otherSide().getImplAttributeName() + "(this);\n");
sb.append(ind(3) + "}\n"); sb.append(ind(3) + "}\n");
...@@ -72,7 +33,7 @@ aspect BackendBidirectionalAPI { ...@@ -72,7 +33,7 @@ aspect BackendBidirectionalAPI {
} }
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
} else { } else {
if (isOpt) { if (isOpt()) {
sb.append(ind(2) + "if (o != null) {\n"); sb.append(ind(2) + "if (o != null) {\n");
sb.append(ind(3) + "o.set" + otherSide().getImplAttributeName() + "(this);\n"); sb.append(ind(3) + "o.set" + otherSide().getImplAttributeName() + "(this);\n");
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
...@@ -84,12 +45,12 @@ aspect BackendBidirectionalAPI { ...@@ -84,12 +45,12 @@ aspect BackendBidirectionalAPI {
sb.append(ind(2) + "return this;\n"); sb.append(ind(2) + "return this;\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
if (isOpt) { if (isOpt()) {
generateExtraOptAPI(sb); generateExtraOptAPI(sb);
} }
} }
public void RelationComponent.generateBiManyMany(StringBuilder sb, RelationComponent opposite) { public void RelationComponent.generateBiManyMany(StringBuilder sb) {
// Get // Get
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "."); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
if (useJastAddNames) { if (useJastAddNames) {
...@@ -115,12 +76,12 @@ aspect BackendBidirectionalAPI { ...@@ -115,12 +76,12 @@ aspect BackendBidirectionalAPI {
sb.append(ind(5) + "changed = true;\n"); sb.append(ind(5) + "changed = true;\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n"); sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n");
sb.append(ind(5) + "if (resolvedElement != null && element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n"); sb.append(ind(5) + "if (resolvedElement != null && element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n");
sb.append(ind(6) + ASTNode.listClass + "<" + getTypeUse().decl() + "> otherList = resolvedElement." + opposite.getImplAttributeField() + ";\n"); sb.append(ind(6) + ASTNode.listClass + "<" + getTypeUse().decl() + "> otherList = resolvedElement." + otherSide().getImplAttributeField() + ";\n");
sb.append(ind(6) + "if (otherList == null) {\n"); sb.append(ind(6) + "if (otherList == null) {\n");
sb.append(ind(7) + "otherList = new " + listClass + "<>();\n"); sb.append(ind(7) + "otherList = new " + listClass + "<>();\n");
sb.append(ind(6) + "}\n"); sb.append(ind(6) + "}\n");
sb.append(ind(6) + "otherList.add(this);\n"); sb.append(ind(6) + "otherList.add(this);\n");
sb.append(ind(6) + "resolvedElement.set" + opposite.getImplAttributeName() + "(otherList);\n"); sb.append(ind(6) + "resolvedElement.set" + otherSide().getImplAttributeName() + "(otherList);\n");
sb.append(ind(5) + "}\n"); sb.append(ind(5) + "}\n");
sb.append(ind(5) + "l.set(i, resolvedElement);\n"); sb.append(ind(5) + "l.set(i, resolvedElement);\n");
sb.append(ind(4) + "}\n"); sb.append(ind(4) + "}\n");
...@@ -195,7 +156,7 @@ aspect BackendBidirectionalAPI { ...@@ -195,7 +156,7 @@ aspect BackendBidirectionalAPI {
} }
public void RelationComponent.generateBiManyOne(StringBuilder sb, RelationComponent opposite) { public void RelationComponent.generateBiManyOne(StringBuilder sb) {
// Get // Get
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "."); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
if (useJastAddNames) { if (useJastAddNames) {
...@@ -221,7 +182,7 @@ aspect BackendBidirectionalAPI { ...@@ -221,7 +182,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(5) + "changed = true;\n"); sb.append(ind(5) + "changed = true;\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n"); sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n");
sb.append(ind(5) + "if (element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n"); sb.append(ind(5) + "if (element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n");
sb.append(ind(6) + getTypeUse().decl() + " oldTarget = resolvedElement." + opposite.getImplAttributeField() + ";\n"); sb.append(ind(6) + getTypeUse().decl() + " oldTarget = resolvedElement." + otherSide().getImplAttributeField() + ";\n");
sb.append(ind(6) + "if (oldTarget != null && oldTarget != this) {\n"); sb.append(ind(6) + "if (oldTarget != null && oldTarget != this) {\n");
sb.append(ind(7) + "oldTarget." + getImplAttributeField() + ".remove(resolvedElement);\n"); sb.append(ind(7) + "oldTarget." + getImplAttributeField() + ".remove(resolvedElement);\n");
sb.append(ind(6) + "}\n"); sb.append(ind(6) + "}\n");
...@@ -229,7 +190,7 @@ aspect BackendBidirectionalAPI { ...@@ -229,7 +190,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(7) + "l.remove(i);\n"); sb.append(ind(7) + "l.remove(i);\n");
sb.append(ind(7) + "i--;\n"); sb.append(ind(7) + "i--;\n");
sb.append(ind(6) + "} else {\n"); sb.append(ind(6) + "} else {\n");
sb.append(ind(7) + "resolvedElement.set" + opposite.getImplAttributeName() + "(this);\n"); sb.append(ind(7) + "resolvedElement.set" + otherSide().getImplAttributeName() + "(this);\n");
sb.append(ind(7) + "l.set(i, resolvedElement);\n"); sb.append(ind(7) + "l.set(i, resolvedElement);\n");
sb.append(ind(6) + "}\n"); sb.append(ind(6) + "}\n");
sb.append(ind(5) + "} else {\n"); sb.append(ind(5) + "} else {\n");
...@@ -306,14 +267,14 @@ aspect BackendBidirectionalAPI { ...@@ -306,14 +267,14 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
public void RelationComponent.generateBiOneMany(StringBuilder sb, boolean isOpt) { public void RelationComponent.generateBiOneMany(StringBuilder sb) {
// Get // Get
generateGetOne(sb); generateGetOne(sb);
// Set // Set
sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized() sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized()
+ "(" + ofTypeDecl() + " o) {\n"); + "(" + ofTypeDecl() + " o) {\n");
if (!isOpt) { if (!isOpt()) {
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
} }
sb.append(ind(2) + "if (" + getImplAttributeField() + " != null) {\n"); sb.append(ind(2) + "if (" + getImplAttributeField() + " != null) {\n");
...@@ -325,8 +286,8 @@ aspect BackendBidirectionalAPI { ...@@ -325,8 +286,8 @@ aspect BackendBidirectionalAPI {
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n");
int ind = isOpt ? 3 : 2; int ind = isOpt() ? 3 : 2;
if (isOpt) { if (isOpt()) {
sb.append(ind(2) + "if (o != null) {\n"); sb.append(ind(2) + "if (o != null) {\n");
} }
sb.append(ind(ind) + ASTNode.listClass + "<" + getTypeUse().decl() + "> list = o." sb.append(ind(ind) + ASTNode.listClass + "<" + getTypeUse().decl() + "> list = o."
...@@ -336,13 +297,13 @@ aspect BackendBidirectionalAPI { ...@@ -336,13 +297,13 @@ aspect BackendBidirectionalAPI {
sb.append(ind(ind) + "}\n"); sb.append(ind(ind) + "}\n");
sb.append(ind(ind) + "list.add(this);\n"); sb.append(ind(ind) + "list.add(this);\n");
sb.append(ind(ind) + "o.set" + otherSide().getImplAttributeName() + "(list);\n"); sb.append(ind(ind) + "o.set" + otherSide().getImplAttributeName() + "(list);\n");
if (isOpt) { if (isOpt()) {
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
} }
sb.append(ind(2) + "return this;\n"); sb.append(ind(2) + "return this;\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
if (isOpt) { if (isOpt()) {
generateExtraOptAPI(sb); generateExtraOptAPI(sb);
} }
} }
......
aspect BackendDirectedAPI { aspect BackendDirectedAPI {
public void RightDirection.generateAPI(StringBuilder sb) {
relation().getLeft().generateDirectedAPI(sb);
}
public void LeftDirection.generateAPI(StringBuilder sb) {
relation().getRight().generateDirectedAPI(sb);
}
public abstract void RelationComponent.generateDirectedAPI(StringBuilder sb); public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb) {
public void OneRelationComponent.generateDirectedAPI(StringBuilder sb) {
generateDirectedZeroOneAPI(sb, false);
}
public void OptionalRelationComponent.generateDirectedAPI(StringBuilder sb) {
generateDirectedZeroOneAPI(sb, true);
generateExtraOptAPI(sb);
}
public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb, boolean optional) {
// Get // Get
generateGetOne(sb); generateGetOne(sb);
// Set // Set
sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl()); sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl());
sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
if (!optional) { if (!isOpt()) {
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
} }
sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n");
sb.append(ind(2) + "return this;\n"); sb.append(ind(2) + "return this;\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
if (isOpt()) {
generateExtraOptAPI(sb);
}
} }
public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) { public void RelationComponent.generateDirectedManyAPI(StringBuilder sb) {
// Get // Get
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "."); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
if (useJastAddNames) { if (useJastAddNames) {
...@@ -130,24 +119,4 @@ aspect BackendDirectedAPI { ...@@ -130,24 +119,4 @@ aspect BackendDirectedAPI {
sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n"); sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
public void RelationComponent.generateExtraOptAPI(StringBuilder sb) {
// has
sb.append(ind(1) + "public boolean " + getTypeUse().decl());
sb.append(".has" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "return ");
if (useJastAddNames) {
sb.append("get" + nameCapitalized());
} else {
sb.append(name());
}
sb.append("() != null;\n");
sb.append(ind(1) + "}\n");
// clear
sb.append(ind(1) + "public void " + getTypeUse().decl());
sb.append(".clear" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n");
sb.append(ind(1) + "}\n");
}
} }
...@@ -250,7 +250,7 @@ aspect NameResolutionHelper { ...@@ -250,7 +250,7 @@ aspect NameResolutionHelper {
} else { } else {
sb.append(relationComponent.name()); sb.append(relationComponent.name());
} }
sb.append(relationComponent.isMany() && useJastAddNames ? "List" : "").append("();\n"); sb.append(relationComponent.isList() && useJastAddNames ? "List" : "").append("();\n");
} }
sb.append(ind(2) + "super.resolveAll();\n"); sb.append(ind(2) + "super.resolveAll();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment