typescript-generator icon indicating copy to clipboard operation
typescript-generator copied to clipboard

Is there a way to only process Java classes (that is: exclude Java interfaces)?

Open sortel64 opened this issue 3 years ago • 8 comments

sortel64 avatar Jan 11 '21 19:01 sortel64

I use ASM generate java bean proxy ,So I can use the proxy to generate typescript bean. When I generate java bean proxy I can control exclude the interfaces or not. Hope to help you

panxiaohong avatar Jan 12 '21 01:01 panxiaohong

Thank you for the suggestion. I'm not sure that I understand ASM. Would you please clarify.

sortel64 avatar Jan 12 '21 01:01 sortel64

`package javatots;

import cz.habarta.typescript.generator.ClassMapping; import cz.habarta.typescript.generator.Input; import cz.habarta.typescript.generator.JsonLibrary; import cz.habarta.typescript.generator.Output; import cz.habarta.typescript.generator.Settings; import cz.habarta.typescript.generator.TypeScriptFileType; import cz.habarta.typescript.generator.TypeScriptGenerator; import cz.habarta.typescript.generator.TypeScriptOutputKind; import java.io.ByteArrayOutputStream; import java.io.Serializable; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type;

public class Test implements Serializable {

static class TestClassLoader extends ClassLoader{ public Class<?> defineClass(String name ,byte[] bytes){ return this.defineClass( name,bytes,0,bytes.length ); } }

public static void main( String[] args ) {

Class<?> testClass = Test.class;
TestClassLoader testClassLoader = new TestClassLoader();


ClassWriter classWriter = new ClassWriter( 0 );
// I set the signature parameter null, So you can parse that from testClass if needed.
// Here I set the interfaces null. So I can exclude the interfaces that I want.
classWriter.visit( Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, testClass.getSimpleName(), null, Type.getInternalName( Object.class ), null );
classWriter.visitEnd();
byte[] bytes = classWriter.toByteArray();
Class<?> proxyClass = testClassLoader.defineClass( testClass.getSimpleName(),bytes);


Settings settings = new Settings();
settings.outputKind = TypeScriptOutputKind.ambientModule;
settings.jsonLibrary = JsonLibrary.jackson2;
settings.classLoader = testClassLoader;
settings.outputKind = TypeScriptOutputKind.module;

TypeScriptGenerator generator = new TypeScriptGenerator( settings );
Input input = Input.from( proxyClass );
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Output to = Output.to( stream );
generator.generateTypeScript( input, to );

System.out.println(stream.toString());

} } `

So you can translate the class to you want with the ASM. And control what to show appear in typescript bean.

panxiaohong avatar Jan 12 '21 03:01 panxiaohong

@sortel64 I am afraid that it is not directly possible. If you have only few interfaces you can exclude them using excludeClasses parameter. Or if your interfaces follow some naming convention maybe it could be possible to exclude them using excludeClassPatterns parameter.

Are your interfaces implemented by classes you want to process? Or are they unrelated to the classes?

vojtechhabarta avatar Jan 12 '21 22:01 vojtechhabarta

@panxiaohong Thank you for the details!

@vojtechhabarta Thanks for the reply Awesome project! Unfortunately there is no specific pattern. The interfaces are implemented by my classes but without an implementation (methods) the interface really don't do me any good in Angular. However, the value for me are the DTOs that are generated for interacting with the backend ReST endpoints. Am I missing something? How do other use the interfaces?

sortel64 avatar Jan 12 '21 23:01 sortel64

I think common case is that there are DTO classes which are POJOs and don't implement any interface apart from some interfaces from Java core like Comparable, Serializable etc. In this case it is possible to exclude those interfaces one by one and get just nice TypeScript declarations.

Do you have for each DTO class also interface? Or what is the purpose of those interfaces?

vojtechhabarta avatar Jan 13 '21 08:01 vojtechhabarta

I do have DTOs (not solely purposed as DTOs; but their intent is to model data e.g. Order), but do implement limited interfaces such as Identity, which has a getId() method. Identity is used for persistence. It is sort of like Comparable, which I exclude since it provides no value in the UI (typescript). I was mainly trying to avoid pulling in all interfaces. I can probably do this using the existing class include/exclude mechanism since almost all models live in a .model package. I was just inquiring.

sortel64 avatar Jan 13 '21 12:01 sortel64

Yes, if you have small number of those interfaces I would exclude them using excludeClasses or excludeClassPatterns parameter.

vojtechhabarta avatar Jan 13 '21 16:01 vojtechhabarta