in packages/jsii-pacmak/lib/targets/java.ts [3126:3270]
private emitModuleFile(mod: spec.Assembly) {
const moduleName = mod.name;
const moduleClass = this.makeModuleClass(moduleName);
const { filePath: moduleResFile, name: moduleResName } =
this.toJavaResourcePath(mod, `${mod.name}.${MODULE_CLASS_NAME}`);
this.code.openFile(moduleResFile);
for (const fqn of Object.keys(this.assembly.types ?? {})) {
this.code.line(`${fqn}=${this.toNativeFqn(fqn, { binaryName: true })}`);
}
this.code.closeFile(moduleResFile);
const moduleFile = this.toJavaFilePath(mod, {
assembly: mod.name,
fqn: `${mod.name}.${MODULE_CLASS_NAME}`,
kind: spec.TypeKind.Class,
name: MODULE_CLASS_NAME,
});
this.code.openFile(moduleFile);
this.code.line(`package ${this.toNativeName(mod).packageName};`);
this.code.line();
if (Object.keys(mod.dependencies ?? {}).length > 0) {
this.code.line('import static java.util.Arrays.asList;');
this.code.line();
}
this.code.line('import java.io.BufferedReader;');
this.code.line('import java.io.InputStream;');
this.code.line('import java.io.InputStreamReader;');
this.code.line('import java.io.IOException;');
this.code.line('import java.io.Reader;');
this.code.line('import java.io.UncheckedIOException;');
this.code.line();
this.code.line('import java.nio.charset.StandardCharsets;');
this.code.line();
this.code.line('import java.util.HashMap;');
if (Object.keys(mod.dependencies ?? {}).length > 0) {
this.code.line('import java.util.List;');
}
this.code.line('import java.util.Map;');
this.code.line();
this.code.line('import software.amazon.jsii.JsiiModule;');
this.code.line();
this.code.line(ANN_INTERNAL);
this.code.openBlock(
`public final class ${MODULE_CLASS_NAME} extends JsiiModule`,
);
this.code.line(
'private static final Map<String, String> MODULE_TYPES = load();',
);
this.code.line();
this.code.openBlock('private static Map<String, String> load()');
this.code.line('final Map<String, String> result = new HashMap<>();');
this.code.line(
`final ClassLoader cl = ${MODULE_CLASS_NAME}.class.getClassLoader();`,
);
this.code.line(
`try (final InputStream is = cl.getResourceAsStream("${moduleResName}");`,
);
this.code.line(
' final Reader rd = new InputStreamReader(is, StandardCharsets.UTF_8);',
);
this.code.openBlock(
' final BufferedReader br = new BufferedReader(rd))',
);
this.code.line('br.lines()');
this.code.line(' .filter(line -> !line.trim().isEmpty())');
this.code.openBlock(' .forEach(line -> ');
this.code.line('final String[] parts = line.split("=", 2);');
this.code.line('final String fqn = parts[0];');
this.code.line('final String className = parts[1];');
this.code.line('result.put(fqn, className);');
this.code.unindent('});'); // Proxy for closeBlock
this.code.closeBlock();
this.code.openBlock('catch (final IOException exception)');
this.code.line('throw new UncheckedIOException(exception);');
this.code.closeBlock();
this.code.line('return result;');
this.code.closeBlock();
this.code.line();
this.code.line(
'private final Map<String, Class<?>> cache = new HashMap<>();',
);
this.code.line();
// ctor
this.code.openBlock(`public ${MODULE_CLASS_NAME}()`);
this.code.line(
`super("${moduleName}", "${
mod.version
}", ${MODULE_CLASS_NAME}.class, "${this.getAssemblyFileName()}");`,
);
this.code.closeBlock(); // ctor
// dependencies
if (mod.dependencies && Object.keys(mod.dependencies).length > 0) {
const deps = [];
for (const dep of Object.keys(mod.dependencies)) {
deps.push(`${this.makeModuleClass(dep)}.class`);
}
this.code.line();
this.code.line('@Override');
this.code.openBlock(
'public List<Class<? extends JsiiModule>> getDependencies()',
);
this.code.line(`return asList(${deps.join(', ')});`);
this.code.closeBlock();
}
this.code.line();
this.code.line('@Override');
this.code.openBlock(
'protected Class<?> resolveClass(final String fqn) throws ClassNotFoundException',
);
this.code.openBlock('if (!MODULE_TYPES.containsKey(fqn))');
this.code.line(
'throw new ClassNotFoundException("Unknown JSII type: " + fqn);',
);
this.code.closeBlock();
this.code.line('String className = MODULE_TYPES.get(fqn);');
this.code.openBlock('if (!this.cache.containsKey(className))');
this.code.line('this.cache.put(className, this.findClass(className));');
this.code.closeBlock();
this.code.line('return this.cache.get(className);');
this.code.closeBlock();
this.code.line();
this.code.openBlock('private Class<?> findClass(final String binaryName)');
this.code.openBlock('try');
this.code.line('return Class.forName(binaryName);');
this.code.closeBlock();
this.code.openBlock('catch (final ClassNotFoundException exception)');
this.code.line('throw new RuntimeException(exception);');
this.code.closeBlock();
this.code.closeBlock();
this.code.closeBlock();
this.code.closeFile(moduleFile);
return moduleClass;
}