Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static fields are included when jsonLibrary=gson #496

Closed
blutorange opened this issue Jun 28, 2020 · 4 comments
Closed

Static fields are included when jsonLibrary=gson #496

blutorange opened this issue Jun 28, 2020 · 4 comments
Labels
Milestone

Comments

@blutorange
Copy link

blutorange commented Jun 28, 2020

When jsonLibrary=gson is set, the type declarations for a Java interface includes its static members.

public class Demo {
  public static String THIS_FIELD_SHOULD_NOT_BE_INCLUDED;
  public String thisShouldBeIncluded;
}

results in something like (when generating classes as interfaces)

export interface Demo {
  THIS_FIELD_SHOULD_NOT_BE_INCLUDED: string ;
  thisShouldBeIncluded: string;
}

Unless I'm missing something and this is by design (?), they should not be included, at least not when generating typescript interfaces:

  • The default new Gson().toJson(someObjectImplementingTheInterfaceWithStaticField) does not seem to includde static fields
  • TypeScript does not support static fields in interfaces
  • jsonLibrary=jackson2 for static fields also does not seem to include static fields on interfaces

A quick look at the code in the debugger seems like a Modifier.isStatic check in the GsonParser should be enough to solve this:

image

@blutorange
Copy link
Author

blutorange commented Jun 28, 2020

For the time being, this library has some very nice hooks that lets us modify the generation process : ) That makes it possible to exclude static fields with a custom extension:

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import cz.habarta.typescript.generator.Extension;
import cz.habarta.typescript.generator.compiler.ModelCompiler.TransformationPhase;
import cz.habarta.typescript.generator.compiler.ModelTransformer;
import cz.habarta.typescript.generator.compiler.SymbolTable;
import cz.habarta.typescript.generator.emitter.EmitterExtensionFeatures;
import cz.habarta.typescript.generator.emitter.TsModel;
import cz.habarta.typescript.generator.parser.BeanModel;
import cz.habarta.typescript.generator.parser.Model;

/**
 * An {@link Extension} that excludes all static fields of interfaces and classes.
 */
public class ExcludeStaticFieldsExtension extends Extension {

  @Override
  public List<TransformerDefinition> getTransformers() {
    return Arrays.asList(new TransformerDefinition(TransformationPhase.BeforeTsModel, new ModelTransformer() {

      @Override
      public TsModel transformModel(SymbolTable symbolTable, TsModel model) {
        return model;
      }

      @Override
      public Model transformModel(SymbolTable symbolTable, Model model) {
        final List<BeanModel> newBeans = model.getBeans() //
            .stream() //
            .map(bean -> bean.withProperties( //
                bean.getProperties() //
                    .stream() //
                    .filter(prop -> !Modifier.isStatic(prop.getOriginalMember().getModifiers())) //
                    .collect(Collectors.toList()))) //
            .collect(Collectors.toList());
        return new Model(newBeans, model.getEnums(), model.getRestApplications());
      }
    }));
  }

  @Override
  public EmitterExtensionFeatures getFeatures() {
    final EmitterExtensionFeatures features = new EmitterExtensionFeatures();
    features.worksWithPackagesMappedToNamespaces = true;
    return features;
  }
}

@vojtechhabarta
Copy link
Owner

Gson is configurable using excludeFieldsWithModifiers method in GsonBuilder. By default it excludes fields that are static or transient. Typescript-generator should by default behave the same. I changed it but it is breaking change. For those who want to generate also static fields as before I added gsonConfiguration/excludeFieldsWithModifiers parameter. Here is Maven example:

<configuration>
    <jsonLibrary>gson</jsonLibrary>
    <gsonConfiguration>
        <excludeFieldsWithModifiers>transient</excludeFieldsWithModifiers>  <!-- static not excluded -->
    </gsonConfiguration>
    ...
</configuration>

@blutorange thanks for this issue and sharing your workaround.

@blutorange
Copy link
Author

Oh, thanks for implementing this. This is better than having to add a custom extension : )

@vojtechhabarta vojtechhabarta added this to the 2.25 milestone Aug 5, 2020
@vojtechhabarta
Copy link
Owner

Released in v2.25.695.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants