Skip to content

Commit

Permalink
feat(map): Codegen for Java Target (#58)
Browse files Browse the repository at this point in the history
* feat(map): add map for javavisitor

Signed-off-by: Jonathan Casey <[email protected]>

* feat(map): update snapshot

Signed-off-by: Jonathan Casey <[email protected]>

* feat(map): add test cases

Signed-off-by: Jonathan Casey <[email protected]>

* remove redundant ternary expression

Signed-off-by: Jonathan Casey <[email protected]>

* feat(map): get type from ModelFile

Signed-off-by: Jonathan Casey <[email protected]>

* chore(deps): upgrade concerto

Signed-off-by: Jonathan Casey <[email protected]>

* fix(csharp):remove semicolon (;) from map property declaration (#60)

fix(csharp):remove ; from map property declaration

Signed-off-by: [email protected] <[email protected]>
Signed-off-by: Jonathan Casey <[email protected]>

* chore: fix package version

Signed-off-by: Jonathan Casey <[email protected]>

* chore(actions): publish v3.16.2 to npm (#61)

Signed-off-by: GitHub <[email protected]>
Signed-off-by: Jonathan-Casey <[email protected]>
Co-authored-by: Jonathan-Casey <[email protected]>
Co-authored-by: Jonathan-Casey <[email protected]>
Signed-off-by: Jonathan Casey <[email protected]>

* feat(map): Codegen for GraphQL Target (#66)

* feat(map): add graphqlvisitor

Signed-off-by: Jonathan Casey <[email protected]>

* test(map): update snapshot

Signed-off-by: Jonathan Casey <[email protected]>

* test(map): adds graphqlvisitor

Signed-off-by: Jonathan Casey <[email protected]>

* test(map): restores sandbox

Signed-off-by: Jonathan Casey <[email protected]>

---------

Signed-off-by: Jonathan Casey <[email protected]>

* feat!(codegen): remove loopback src (#59)

feat(codegen): remove loopback src

Signed-off-by: Jonathan Casey <[email protected]>

* chore(deps-dev): bump @babel/traverse from 7.22.11 to 7.23.2 (#67)

Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.11 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: Jonathan Casey <[email protected]>

* test(codegen) update HR model to use multiple namespaces (#68)

Signed-off-by: Dan Selman <[email protected]>
Signed-off-by: Jonathan Casey <[email protected]>

* feat(map): update snapshot

Signed-off-by: Jonathan Casey <[email protected]>

* chore(deps): upgrade concerto

Signed-off-by: Jonathan Casey <[email protected]>

* chore(deps): upgrade concerto

Signed-off-by: Jonathan Casey <[email protected]>

* test(*): snapshot update

Signed-off-by: Jonathan Casey <[email protected]>

* test(*): snapshot update

Signed-off-by: Jonathan Casey <[email protected]>

* feat(map): write util import

Signed-off-by: Jonathan Casey <[email protected]>

* test(*): fix regressions

Signed-off-by: Jonathan Casey <[email protected]>

* test(*): add test coverage for map imports

Signed-off-by: Jonathan Casey <[email protected]>

* test(*): uses isMap util fun

Signed-off-by: Jonathan Casey <[email protected]>

---------

Signed-off-by: Jonathan Casey <[email protected]>
Signed-off-by: [email protected] <[email protected]>
Signed-off-by: GitHub <[email protected]>
Signed-off-by: Jonathan-Casey <[email protected]>
Signed-off-by: dependabot[bot] <[email protected]>
Signed-off-by: Dan Selman <[email protected]>
Co-authored-by: Ragi Dayananda <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonathan-Casey <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dan Selman <[email protected]>
  • Loading branch information
6 people authored Nov 6, 2023
1 parent 26a0b79 commit e3111a0
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 15 deletions.
16 changes: 15 additions & 1 deletion lib/codegen/fromcto/java/javavisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ class JavaVisitor {
parameters.fileWriter.writeLine(0, `import ${namespace}.${typeName};` );
});

let hasImportedJavaMap = false;
classDeclaration.getOwnProperties().forEach(p => {
if(ModelUtil.isMap(p) && !hasImportedJavaMap) {
parameters.fileWriter.writeLine(0, 'import java.util.HashMap;');
parameters.fileWriter.writeLine(0, 'import java.util.Map;');
hasImportedJavaMap = true;
}
});

parameters.fileWriter.writeLine(0, 'import com.fasterxml.jackson.annotation.*;');
parameters.fileWriter.writeLine(0, '');

Expand Down Expand Up @@ -278,7 +287,12 @@ class JavaVisitor {
parameters.fileWriter.writeLine(1, '}');
break;
default:
parameters.fileWriter.writeLine(1, 'private ' + fieldType + ' ' + fieldName + ';' );
if (ModelUtil.isMap(field)) {
const decl = field.getModelFile().getType(field.ast.type.name);
parameters.fileWriter.writeLine(1, `private Map<${this.toJavaType(decl.getKey().getType())}, ${this.toJavaType(decl.getValue().getType())}> ${field.getName()} = new HashMap<>();`);
} else {
parameters.fileWriter.writeLine(1, 'private ' + fieldType + ' ' + fieldName + ';' );
}
}
} else {
parameters.fileWriter.writeLine(1, 'private ' + fieldType + ' ' + fieldName + ';' );
Expand Down
32 changes: 20 additions & 12 deletions test/codegen/__snapshots__/codegen.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1065,17 +1065,19 @@ import concerto.Asset;
import concerto.Transaction;
import concerto.Participant;
import concerto.Event;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.*;

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "$class")
public class Company extends Concept {
private String name;
private Address headquarters;
private CompanyProperties companyProperties;
private EmployeeDirectory employeeDirectory;
private EmployeeTShirtSizes employeeTShirtSizes;
private EmployeeProfiles employeeProfiles;
private EmployeeSocialSecurityNumbers employeeSocialSecurityNumbers;
private Map<String, String> companyProperties = new HashMap<>();
private Map<SSN, Employee> employeeDirectory = new HashMap<>();
private Map<SSN, TShirtSizeType> employeeTShirtSizes = new HashMap<>();
private Map<String, Concept> employeeProfiles = new HashMap<>();
private Map<String, SSN> employeeSocialSecurityNumbers = new HashMap<>();
public String getName() {
return this.name;
}
Expand Down Expand Up @@ -1253,6 +1255,8 @@ import concerto.Asset;
import concerto.Transaction;
import concerto.Participant;
import concerto.Event;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.*;

@JsonIgnoreProperties({"id"})
Expand All @@ -1272,7 +1276,7 @@ public abstract class Person extends Participant {
private String ssn;
private double height;
private java.util.Date dob;
private NextOfKin nextOfKin;
private Map<KinName, KinTelephone> nextOfKin = new HashMap<>();
public String getEmail() {
return this.email;
}
Expand Down Expand Up @@ -6613,17 +6617,19 @@ import concerto.Asset;
import concerto.Transaction;
import concerto.Participant;
import concerto.Event;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.*;

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "$class")
public class Company extends Concept {
private String name;
private Address headquarters;
private CompanyProperties companyProperties;
private EmployeeDirectory employeeDirectory;
private EmployeeTShirtSizes employeeTShirtSizes;
private EmployeeProfiles employeeProfiles;
private EmployeeSocialSecurityNumbers employeeSocialSecurityNumbers;
private Map<String, String> companyProperties = new HashMap<>();
private Map<SSN, Employee> employeeDirectory = new HashMap<>();
private Map<SSN, TShirtSizeType> employeeTShirtSizes = new HashMap<>();
private Map<String, Concept> employeeProfiles = new HashMap<>();
private Map<String, SSN> employeeSocialSecurityNumbers = new HashMap<>();
public String getName() {
return this.name;
}
Expand Down Expand Up @@ -6801,6 +6807,8 @@ import concerto.Asset;
import concerto.Transaction;
import concerto.Participant;
import concerto.Event;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.*;

@JsonIgnoreProperties({"id"})
Expand All @@ -6820,7 +6828,7 @@ public abstract class Person extends Participant {
private String ssn;
private double height;
private java.util.Date dob;
private NextOfKin nextOfKin;
private Map<KinName, KinTelephone> nextOfKin = new HashMap<>();
public String getEmail() {
return this.email;
}
Expand Down
14 changes: 13 additions & 1 deletion test/codegen/fromcto/java/javamissingplugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ const sinon = require('sinon');

const JavaVisitor = require('../../../../lib/codegen/fromcto/java/javavisitor.js');
const AbstractPlugin = require('../../../../lib/codegen/abstractplugin.js');
const ModelUtil = require('@accordproject/concerto-core').ModelUtil;

const ClassDeclaration = require('@accordproject/concerto-core').ClassDeclaration;
const EnumDeclaration = require('@accordproject/concerto-core').EnumDeclaration;
const FileWriter = require('@accordproject/concerto-util').FileWriter;

let sandbox = sinon.createSandbox();

describe('JavaMissingPlugin', function () {
let javaVisit;
let mockFileWriter;
Expand Down Expand Up @@ -115,6 +118,15 @@ describe('JavaMissingPlugin', function () {

sinon.stub(javaVisit, 'startClassFile');
sinon.stub(javaVisit, 'endClassFile');

sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return true;
});
});

afterEach(() => {
sandbox.restore();

});

it('should fail to write a class declaration and call accept on each property', () => {
Expand All @@ -126,4 +138,4 @@ describe('JavaMissingPlugin', function () {
});
});

});
});
82 changes: 81 additions & 1 deletion test/codegen/fromcto/java/javavisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const sinon = require('sinon');
const JavaVisitor = require('../../../../lib/codegen/fromcto/java/javavisitor.js');

const ClassDeclaration = require('@accordproject/concerto-core').ClassDeclaration;
const MapDeclaration = require('@accordproject/concerto-core').MapDeclaration;
const ModelUtil = require('@accordproject/concerto-core').ModelUtil;
const EnumDeclaration = require('@accordproject/concerto-core').EnumDeclaration;
const EnumValueDeclaration = require('@accordproject/concerto-core').EnumValueDeclaration;
const Field = require('@accordproject/concerto-core').Field;
Expand All @@ -29,12 +31,21 @@ const ModelManager = require('@accordproject/concerto-core').ModelManager;
const RelationshipDeclaration = require('@accordproject/concerto-core').RelationshipDeclaration;
const FileWriter = require('@accordproject/concerto-util').FileWriter;

let sandbox = sinon.createSandbox();

describe('JavaVisitor', function () {
let javaVisit;
let mockFileWriter;
beforeEach(() => {
javaVisit = new JavaVisitor();
mockFileWriter = sinon.createStubInstance(FileWriter);
sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return false;
});
});

afterEach(() => {
sandbox.restore();
});

describe('visit', () => {
Expand Down Expand Up @@ -376,6 +387,36 @@ describe('JavaVisitor', function () {
acceptSpy.withArgs(javaVisit, Object.assign({},param,{mode:'setter'})).calledTwice.should.be.ok;
mockEndClassFile.withArgs(mockClassDeclaration, param).calledOnce.should.be.ok;
});

it('should write a class declaration, including imports for java.util Map & HashMap types', () => {
mockClassDeclaration.getIdentifierFieldName.returns('employeeID');
sandbox.restore();
sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return true;
});
javaVisit.visitClassDeclaration(mockClassDeclaration, param);

mockStartClassFile.withArgs(mockClassDeclaration, param).calledOnce.should.be.ok;
param.fileWriter.writeLine.callCount.should.deep.equal(9);
param.fileWriter.writeLine.getCall(0).args.should.deep.equal([0, 'import fruit.oranges;']);
param.fileWriter.writeLine.getCall(1).args.should.deep.equal([0, 'import fruit.apples;']);
param.fileWriter.writeLine.getCall(2).args.should.deep.equal([0, 'import java.util.HashMap;']);
param.fileWriter.writeLine.getCall(3).args.should.deep.equal([0, 'import java.util.Map;']);
param.fileWriter.writeLine.getCall(4).args.should.deep.equal([0, 'import com.fasterxml.jackson.annotation.*;']);
param.fileWriter.writeLine.getCall(5).args.should.deep.equal([0, '']);
param.fileWriter.writeLine.getCall(6).args.should.deep.equal([0, 'public class Bob {']);
param.fileWriter.writeLine.getCall(7).args.should.deep.equal([1, `
// the accessor for the identifying field
public String getID() {
return this.getEmployeeID();
}
`]);
param.fileWriter.writeLine.getCall(8).args.should.deep.equal([0, '}']);
acceptSpy.withArgs(javaVisit, Object.assign({},param,{mode:'field'})).calledTwice.should.be.ok;
acceptSpy.withArgs(javaVisit, Object.assign({},param,{mode:'getter'})).calledTwice.should.be.ok;
acceptSpy.withArgs(javaVisit, Object.assign({},param,{mode:'setter'})).calledTwice.should.be.ok;
mockEndClassFile.withArgs(mockClassDeclaration, param).calledOnce.should.be.ok;
});
});

describe('visitField', () => {
Expand Down Expand Up @@ -413,6 +454,45 @@ describe('JavaVisitor', function () {
param.fileWriter.writeLine.withArgs(1, 'private JavaType[] Bob;').calledOnce.should.be.ok;
});

it('should write a line with a HashMap', () => {
let param = {
fileWriter: mockFileWriter,
mode: 'field'
};

sandbox.restore();
sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return true;
});

const mockField = sinon.createStubInstance(Field);
const getType = sinon.stub();

mockField.ast = { type: { name: 'Dummy Value'} };
mockField.getModelFile.returns({ getType: getType });

const mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
const getKeyType = sinon.stub();
const getValueType = sinon.stub();

mockField.getName.returns('Bob');
mockField.getType.returns('SpecialType');

getType.returns(mockMapDeclaration);
getKeyType.returns('String');
getValueType.returns('String');
mockField.getName.returns('Map1');
mockMapDeclaration.getName.returns('Map1');
mockMapDeclaration.isMapDeclaration.returns(true);
mockMapDeclaration.getKey.returns({ getType: getKeyType });
mockMapDeclaration.getValue.returns({ getType: getValueType });

javaVisit.visitField(mockField,param);

param.fileWriter.writeLine.withArgs(1, 'private Map<String, String> Map1 = new HashMap<>();').calledOnce.should.be.ok;
sandbox.reset();
});

it('should write a line defining a field', () => {
let mockField = sinon.createStubInstance(Field);
mockField.isField.returns(true);
Expand Down Expand Up @@ -673,4 +753,4 @@ describe('JavaVisitor', function () {
javaVisit.toJavaType('Penguin').should.deep.equal('Penguin');
});
});
});
});

0 comments on commit e3111a0

Please sign in to comment.