diff --git a/spec/jastadd/Backend.jadd b/spec/jastadd/Backend.jadd index 5d4404445f0ea075eb6f3e4d6d48ef53d304603c..d9da1c4ef99e9ff0d081994bcd326aebfc00075d 100644 --- a/spec/jastadd/Backend.jadd +++ b/spec/jastadd/Backend.jadd @@ -206,7 +206,7 @@ aspect BackendBidirectionalAPI { l.generateBiOneOne(sb, false); r.generateBiOneOne(sb, true); } else if (r.multiplicityMany()) { - l.generateBiOneMany(sb); + l.generateBiOneMany(sb, false); r.generateBiManyOne(sb); } } else if (l.multiplicityOpt()) { @@ -217,14 +217,16 @@ aspect BackendBidirectionalAPI { l.generateBiOneOne(sb, true); r.generateBiOneOne(sb, true); } else if (r.multiplicityMany()) { - + l.generateBiOneMany(sb, true); + r.generateBiManyOne(sb); } } else if (l.multiplicityMany()) { if (r.multiplicityOne()) { l.generateBiManyOne(sb); - r.generateBiOneMany(sb); + r.generateBiOneMany(sb, false); } else if (r.multiplicityOpt()) { - + l.generateBiManyOne(sb); + r.generateBiOneMany(sb, true); } else if (r.multiplicityMany()) { l.generateBiManyMany(sb); r.generateBiManyMany(sb); @@ -357,7 +359,7 @@ aspect BackendBidirectionalAPI { sb.append(ind(1) + "}\n"); } - public void RelationComponent.generateBiOneMany(StringBuilder sb) { + public void RelationComponent.generateBiOneMany(StringBuilder sb, boolean isOpt) { // Get sb.append(ind(1) + "public " + ofTypeDecl() + " " + toTypeDecl()); sb.append("." + name() + "() {\n"); @@ -367,7 +369,9 @@ aspect BackendBidirectionalAPI { // Set sb.append(ind(1) + "public void " + toTypeDecl() + ".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); - sb.append(ind(2) + "assertNotNull(o);\n"); + if (!isOpt) { + sb.append(ind(2) + "assertNotNull(o);\n"); + } sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null) {\n"); sb.append(ind(3) + "ArrayList<" + toTypeDecl() + "> list2 = get" + getImplAttributeName() + "()." + "get" + otherSide().getImplAttributeName() + "();\n"); @@ -376,14 +380,30 @@ aspect BackendBidirectionalAPI { + otherSide().getImplAttributeName() + "(list2);\n"); sb.append(ind(2) + "}\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); - sb.append(ind(2) + "ArrayList<" + toTypeDecl() + "> list = o.get" + + int ind = isOpt ? 3 : 2; + if (isOpt) { + sb.append(ind(2) + "if (o != null) {\n"); + } + sb.append(ind(ind) + "ArrayList<" + toTypeDecl() + "> list = o.get" + otherSide().getImplAttributeName() + "();\n"); - sb.append(ind(2) + "if (list == null) {\n"); - sb.append(ind(3) + "list = new ArrayList<>();\n"); - sb.append(ind(2) + "}\n"); - sb.append(ind(2) + "list.add(this);\n"); - sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(list);\n"); + sb.append(ind(ind) + "if (list == null) {\n"); + sb.append(ind(ind+1) + "list = new ArrayList<>();\n"); + sb.append(ind(ind) + "}\n"); + sb.append(ind(ind) + "list.add(this);\n"); + sb.append(ind(ind) + "o.set" + otherSide().getImplAttributeName() + "(list);\n"); + if (isOpt) { + sb.append(ind(2) + "}\n"); + } sb.append(ind(1) + "}\n"); + + // has + if (isOpt) { + sb.append(ind(1) + "public boolean " + toTypeDecl()); + sb.append(".has" + nameCapitalized() + "() {\n"); + sb.append(ind(2) + "return " + name() + "() != null;\n"); + sb.append(ind(1) + "}\n"); + } } } diff --git a/test/Test.java b/test/Test.java index e63a480e945e26c38a1fca112009585e4dca7463..fe6be7882cba6f9fda9bcb08496fd6b5933d3c37 100644 --- a/test/Test.java +++ b/test/Test.java @@ -315,6 +315,54 @@ public class Test { * rel A.bi6? <-> B.bi6*; */ private void testBi6() { + setup(); + a2.setBi6(b2); + + assertNull(a1.bi6()); + assertSame(a2.bi6(), b2); + assertEquals(b1.bi6(), Arrays.asList()); + assertEquals(b2.bi6(), Arrays.asList(a2)); + assertEquals(b3.bi6(), Arrays.asList()); + + a2.setBi6(b3); + + assertNull(a1.bi6()); + assertSame(a2.bi6(), b3); + assertEquals(b1.bi6(), Arrays.asList()); + assertEquals(b2.bi6(), Arrays.asList()); + assertEquals(b3.bi6(), Arrays.asList(a2)); + + a1.setBi6(b3); + a3.setBi6(b3); + + assertSame(a1.bi6(), b3); + assertSame(a2.bi6(), b3); + assertSame(a3.bi6(), b3); + assertEquals(b1.bi6(), Arrays.asList()); + assertEquals(b2.bi6(), Arrays.asList()); + assertEquals(b3.bi6(), Arrays.asList(a2, a1, a3)); + + a2.setBi6(b1); + + assertSame(a1.bi6(), b3); + assertSame(a2.bi6(), b1); + assertSame(a3.bi6(), b3); + assertEquals(b1.bi6(), Arrays.asList(a2)); + assertEquals(b2.bi6(), Arrays.asList()); + assertEquals(b3.bi6(), Arrays.asList(a1, a3)); + + a2.setBi6(null); + + assertSame(a1.bi6(), b3); + assertNull(a2.bi6()); + assertSame(a3.bi6(), b3); + assertEquals(b1.bi6(), Arrays.asList()); + assertEquals(b2.bi6(), Arrays.asList()); + assertEquals(b3.bi6(), Arrays.asList(a1, a3)); + + assertTrue(a1.hasBi6()); + assertFalse(a2.hasBi6()); + assertTrue(a3.hasBi6()); } @@ -372,6 +420,47 @@ public class Test { * rel A.bi8* <-> B.bi8?; */ private void testBi8() { + setup(); + a2.addToBi8(b2); + + assertEquals(a1.bi8(), Arrays.asList()); + assertEquals(a2.bi8(), Arrays.asList(b2)); + assertNull(b1.bi8()); + assertSame(b2.bi8(), a2); + assertNull(b3.bi8()); + + a2.addToBi8(b3); + a1.addToBi8(b2); + + assertEquals(a1.bi8(), Arrays.asList(b2)); + assertEquals(a2.bi8(), Arrays.asList(b3)); + assertNull(b1.bi8()); + assertSame(b2.bi8(), a1); + assertSame(b3.bi8(), a2); + + a1.addToBi8(b1); + + assertEquals(a1.bi8(), Arrays.asList(b2, b1)); + assertEquals(a2.bi8(), Arrays.asList(b3)); + assertSame(b1.bi8(), a1); + assertSame(b2.bi8(), a1); + assertSame(b3.bi8(), a2); + + a1.addToBi8(b1); + + assertEquals(a1.bi8(), Arrays.asList(b2, b1)); + assertEquals(a2.bi8(), Arrays.asList(b3)); + assertSame(b1.bi8(), a1); + assertSame(b2.bi8(), a1); + assertSame(b3.bi8(), a2); + + a1.removeFromBi8(b1); + + assertEquals(a1.bi8(), Arrays.asList(b2)); + assertEquals(a2.bi8(), Arrays.asList(b3)); + assertNull(b1.bi8()); + assertSame(b2.bi8(), a1); + assertSame(b3.bi8(), a2); }