Skip to content

Commit

Permalink
feat: import objects referenced using avro namespaces (#246)
Browse files Browse the repository at this point in the history
* package and import files that are in a different namespace

* update eslint to support optional chaining

* moved stripPackageName function to scsLib
  • Loading branch information
CameronRushton authored Mar 1, 2022
1 parent c48bc1b commit 357cde4
Show file tree
Hide file tree
Showing 11 changed files with 1,352 additions and 1,811 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ env:
jest/globals: true

parserOptions:
ecmaVersion: 2018
ecmaVersion: 2020

plugins:
- jest
Expand Down
47 changes: 46 additions & 1 deletion filters/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,50 @@ function stringify(obj) {
}
filter.stringify = stringify;

function extraImports([asyncapi, params]) {
return getExtraImports(asyncapi);
}
filter.extraImports = extraImports;

function getExtraImports(asyncapi) {
const schemaImports = [];
const channelOperationInfos = [];
for (const channelName in asyncapi.channels()) {
const channel = asyncapi.channels()[channelName];
if (channel.hasPublish()) {
channelOperationInfos.push(channel.publish());
}
if (channel.hasSubscribe()) {
channelOperationInfos.push(channel.subscribe());
}
}
if (channelOperationInfos.length > 0) {
channelOperationInfos.forEach(channelOperationInfo => {
const fullPackagePath = getPayloadPackage(channelOperationInfo);
if (fullPackagePath) {
schemaImports.push(fullPackagePath);
}
});
}
return schemaImports;
}

function getPayloadPackage(pubOrSub) {
let fullPackagePath;
if (!pubOrSub.hasMultipleMessages()) {
const payload = pubOrSub.message()?.payload();
if (payload) {
const type = payload.type();
const importName = payload.ext('x-parser-schema-id');
// This is a schema within a package - like an avro schema in a namespace. We're hoping the full thing is part of the x-schema-parser-id.
if ((!type || type === 'object') && importName.includes('.')) {
fullPackagePath = importName;
}
}
}
return fullPackagePath;
}

// Returns true if any property names will be different between json and java.
function checkPropertyNames(name, schema) {
const ret = false;
Expand Down Expand Up @@ -896,7 +940,8 @@ function getMessagePayloadType(message) {

if (!type || type === 'object') {
ret = payload.ext('x-parser-schema-id');
ret = _.camelCase(ret);
const { className } = scsLib.stripPackageName(ret);
ret = _.camelCase(className);
ret = _.upperFirst(ret);
} else {
ret = getType(type, payload.format()).javaType;
Expand Down
13 changes: 3 additions & 10 deletions lib/applicationModel.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const ModelClass = require('./modelClass.js');
const debugApplicationModel = require('debug')('applicationModel');
const _ = require('lodash');
const ScsLib = require('./scsLib.js');
const scsLib = new ScsLib();
const instanceMap = new Map();

class ApplicationModel {
Expand Down Expand Up @@ -156,7 +158,7 @@ class ApplicationModel {
modelClass.setCanBeInnerClass(false);
}

const { className, javaPackage } = this.stripPackageName(schemaName);
const { className, javaPackage } = scsLib.stripPackageName(schemaName);
modelClass.setJavaPackage(javaPackage);
modelClass.setClassName(className);
debugApplicationModel(`schemaName ${schemaName} className: ${modelClass.getClassName()} super: ${modelClass.getSuperClassName()} javaPackage: ${javaPackage}`);
Expand Down Expand Up @@ -186,15 +188,6 @@ class ApplicationModel {
return schemaName;
}

stripPackageName(schemaName) {
// If there is a dot in the schema name, it's probably an Avro schema with a fully qualified name (including the namespace.)
const indexOfDot = schemaName.lastIndexOf('.');
if (indexOfDot > 0) {
return { className: schemaName.substring(indexOfDot + 1), javaPackage: schemaName.substring(0, indexOfDot) };
}
return { className: schemaName, javaPackage: undefined };
}

reset() {
instanceMap.forEach((val) => {
val.superClassMap = null;
Expand Down
15 changes: 15 additions & 0 deletions lib/scsLib.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,21 @@ class ScsLib {
return isProvider ? channel.subscribe() : channel.publish();
}

/**
* Takes a string, splits on the last instance of '.' (dot) if it exists and returns an object of the separated pieces.
*
* @param {String} dotSeparatedName Example: 'com.solace.api.Schema'.
* @returns {Object} { javaPackage, className } Example: { javaPackage: "com.solace.api", className: "Schema" }.
*/
stripPackageName(dotSeparatedName) {
// If there is a dot in the schema name, it's probably an Avro schema with a fully qualified name (including the namespace.)
const indexOfDot = dotSeparatedName.lastIndexOf('.');
if (indexOfDot > 0) {
return { javaPackage: dotSeparatedName.substring(0, indexOfDot), className: dotSeparatedName.substring(indexOfDot + 1) };
}
return { className: dotSeparatedName };
}

initReservedWords() {
// This is the set of Java reserved words, to ensure that we don't generate any by mistake.
ScsLib.javaKeywords = new Set();
Expand Down
Loading

0 comments on commit 357cde4

Please sign in to comment.