├── .gitignore ├── .travis.yml ├── LICENCE ├── README.md ├── img └── j2ts-workflow.png ├── java2typescript-jackson ├── README.md ├── pom.xml └── src │ ├── main │ └── java │ │ └── java2typescript │ │ └── jackson │ │ └── module │ │ ├── Configuration.java │ │ ├── DefinitionGenerator.java │ │ ├── StaticFieldExporter.java │ │ ├── conf │ │ └── typename │ │ │ ├── SimpleJacksonTSTypeNamingStrategy.java │ │ │ ├── TSTypeNamingStrategy.java │ │ │ └── WithEnclosingClassTSTypeNamingStrategy.java │ │ ├── grammar │ │ ├── AnyType.java │ │ ├── ArrayType.java │ │ ├── BooleanType.java │ │ ├── ClassType.java │ │ ├── EnumType.java │ │ ├── FunctionType.java │ │ ├── MapType.java │ │ ├── Module.java │ │ ├── NullType.java │ │ ├── NumberType.java │ │ ├── StaticClassType.java │ │ ├── StringType.java │ │ ├── TypeDeclarationType.java │ │ ├── VoidType.java │ │ └── base │ │ │ ├── AbstractNamedType.java │ │ │ ├── AbstractPrimitiveType.java │ │ │ ├── AbstractType.java │ │ │ └── Value.java │ │ ├── visitors │ │ ├── ABaseTSJsonFormatVisitor.java │ │ ├── TSJsonAnyFormatVisitor.java │ │ ├── TSJsonArrayFormatVisitor.java │ │ ├── TSJsonBooleanFormatVisitor.java │ │ ├── TSJsonFormatVisitorWrapper.java │ │ ├── TSJsonMapFormatVisitor.java │ │ ├── TSJsonNullFormatVisitor.java │ │ ├── TSJsonNumberFormatVisitor.java │ │ ├── TSJsonObjectFormatVisitor.java │ │ └── TSJsonStringFormatVisitor.java │ │ └── writer │ │ ├── AmbientModuleFormatWriter.java │ │ ├── CustomAbstractTypeWriter.java │ │ ├── EnumTypeToEnumPatternWriter.java │ │ ├── EnumTypeToStringLiteralTypeWriter.java │ │ ├── ExternalModuleFormatWriter.java │ │ ├── InternalModuleFormatWriter.java │ │ ├── ModuleWriter.java │ │ ├── SortUtil.java │ │ └── WriterPreferences.java │ └── test │ ├── java │ └── java2typescript │ │ └── jackson │ │ └── module │ │ ├── ClassWithoutFieldsTest.java │ │ ├── CustomTypeDefinitionGeneratorTest.java │ │ ├── DefinitionGeneratorTest.java │ │ ├── ExcludedMethodsTest.java │ │ ├── StaticFieldExporterTest.java │ │ ├── TypeRenamingWithAnnotationTest.java │ │ ├── TypeRenamingWithEnclosingClassTest.java │ │ ├── WriterPreferencesTest.java │ │ └── util │ │ ├── ExpectedOutputChecker.java │ │ └── TestUtil.java │ └── resources │ └── java2typescript │ └── jackson │ └── module │ ├── ClassWithoutFieldsTest.classWithOnlyMethod.d.ts │ ├── ClassWithoutFieldsTest.classWithoutFields.d.ts │ ├── ClassWithoutFieldsTest.referencesClassWithoutFields.d.ts │ ├── CustomTypeDefinitionGeneratorTest.classWithCustomTypeFields.d.ts │ ├── CustomTypeDefinitionGeneratorTest.declareTypeInsteadOfEmittingInterface.d.ts │ ├── DefinitionGeneratorTest.ambientModuleFormat.d.ts │ ├── DefinitionGeneratorTest.classWithMethodReturningThis.d.ts │ ├── DefinitionGeneratorTest.externalModuleFormat.d.ts │ ├── DefinitionGeneratorTest.internalModuleFormat.d.ts │ ├── ExcludedMethodsTest.testExcludedMethods.d.ts │ ├── TypeRenamingWithAnnotationTest.nameChangedWithAnnotation.d.ts │ ├── TypeRenamingWithEnclosingClassTest.twoClassesWithSameName.d.ts │ ├── WriterPreferencesTest.enumPatternBaseNotAddedWhenNotNeeded.d.ts │ ├── WriterPreferencesTest.enumToEnumPattern.d.ts │ ├── WriterPreferencesTest.enumToStringLiteralType.d.ts │ ├── WriterPreferencesTest.enumToStringLiteralTypeWithConstants.d.ts │ ├── WriterPreferencesTest.indentWithTabs.d.ts │ └── WriterPreferencesTest.sortOutputTypesAndVars.d.ts ├── java2typescript-jaxrs ├── pom.xml └── src │ ├── main │ ├── java │ │ └── java2typescript │ │ │ └── jaxrs │ │ │ ├── ServiceDescriptorGenerator.java │ │ │ └── model │ │ │ ├── HttpMethod.java │ │ │ ├── Param.java │ │ │ ├── ParamType.java │ │ │ ├── RestMethod.java │ │ │ └── RestService.java │ └── resources │ │ └── java2typescript │ │ └── jaxrs │ │ └── module-template.js │ └── test │ └── java │ └── java2typescript │ └── jaxrs │ └── DescriptorGeneratorTest.java ├── java2typescript-maven-plugin ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── java2typescript │ │ │ └── maven │ │ │ └── plugin │ │ │ ├── IncludeProjectDependenciesComponentConfigurator.java │ │ │ └── MainMojo.java │ └── resources │ │ └── org │ │ └── java2typescript │ │ └── maven │ │ └── plugin │ │ └── module-template.js │ └── site │ ├── apt │ └── index.apt.vm │ └── site.xml ├── pom.xml ├── sample-web-app-client └── pom.xml ├── sample-web-app-server ├── .gitignore ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ ├── Starter.java │ │ ├── config │ │ └── AppConfig.java │ │ ├── exceptions │ │ ├── PersonAlreadyExistsException.java │ │ └── PersonNotFoundException.java │ │ ├── model │ │ └── Person.java │ │ ├── rs │ │ ├── JaxRsApiApplication.java │ │ └── PeopleRestService.java │ │ └── services │ │ └── PeopleService.java │ └── resources │ ├── META-INF │ └── cxf │ │ └── org.apache.cxf.Logger │ └── WEB-INF │ ├── index.html │ ├── js │ ├── People.js │ ├── PeopleApp.js │ └── jquery.js │ └── ts │ ├── People.d.ts │ └── PeopleApp.ts └── sample-web-app ├── .gitignore ├── README.md ├── pom.xml └── src └── main ├── java └── com │ └── example │ ├── Starter.java │ ├── config │ └── AppConfig.java │ ├── exceptions │ ├── PersonAlreadyExistsException.java │ └── PersonNotFoundException.java │ ├── model │ └── Person.java │ ├── rs │ ├── JaxRsApiApplication.java │ └── PeopleRestService.java │ └── services │ └── PeopleService.java └── resources ├── META-INF └── cxf │ └── org.apache.cxf.Logger └── WEB-INF ├── index.html ├── js ├── People.js ├── PeopleApp.js └── jquery.js └── ts ├── People.d.ts └── PeopleApp.ts /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .settings 3 | .classpath 4 | .project 5 | .idea 6 | **/*.iml 7 | release.properties 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Release](https://img.shields.io/github/release/raphaeljolivet/java2typescript.svg?label=latest release is)](https://jitpack.io/#raphaeljolivet/java2typescript) 2 | 3 | Continuous Integration [![Build Status](https://travis-ci.org/raphaeljolivet/java2typescript.svg)](https://travis-ci.org/raphaeljolivet/java2typescript/) (for last commit on any branch) 4 | 5 | 6 | ## Purpose 7 | 8 | **Java2Typescript** provides a bridge between a **Java** REST service definition and a **Typescript** client. 9 | 10 | It enables you to expose a full DTO model and REST services API as a clean typescript definition file, thus enabling strong type-checking on the models of your application. 11 | 12 | This project is composed of 3 modules : 13 | * **[java2typescript-jackson](java2typescript-jackson)**: A [Jackson](http://jackson.codehaus.org/) module that generates **typescript** definition files for Java classes, using a Jackson ObjectMapper. 14 | * **[java2typescript-jaxrs](java2typescript-jaxrs)**: An extension to **java2typescript-jackson** that takes a [JAX-RS](https://jax-rs-spec.java.net/) annotated java class and produces both : 15 | * A Typescript definition file of the service (`.d.ts`), together with description of all needed DTO objects. 16 | * An `.js` implementation of the above definition as a REST client stub. 17 | * **[java2typescript-maven-plugin](java2typescript-maven-plugin)**: A maven plugin to automate the generation of a `.d.ts` file and a `.js` implementation of REST services. 18 | * A **[sample web application](sample-web-app)** that demonstrate the usage of **java2typescript** 19 | 20 | ## Big picture 21 | 22 | Here is a schema of the workflow for a typical project using **j2ts** : 23 | ![j2ts workflow](img/j2ts-workflow.png) 24 | 25 | There are only two source files here : 26 | * Server side: `AppRest.java` with annotated JAX-RS services 27 | * Client side: `App.ts` 28 | 29 | The detailed workflow is: 30 | 31 | 1. `AppRest.java` contains the annotated **JAX-RS** service definition 32 | 2. **j2ts** compiles the REST service definition into a `.d.ts` description file, and a `.js` file (runtime implementation) 33 | 3. `App.ts` imports and uses the `.d.ts` file 34 | 4. `App.ts` is compiled into a `App.js` file (by typescript compiler) 35 | 36 | # Usage 37 | 38 | Please refer to the documentation of the [maven plugin](java2typescript-maven-plugin) and the example below 39 | 40 | # Example 41 | 42 | **java2typescript** handles all the HTTP REST standard itself, and provide REST services as vanilla Typescript methods, regardless of the HTTP method / mime to use. 43 | 44 | Consider the following JAX-RS service 45 | ```java 46 | @Path( "/people" ) 47 | public interface PeopleRestService { 48 | 49 | 50 | @Produces( { MediaType.APPLICATION_JSON } ) 51 | @GET 52 | public Collection< Person > getPeoples( @QueryParam( "page") @DefaultValue( "1" ) final int page ) { 53 | return peopleService.getPeople( page, 5 ); 54 | } 55 | 56 | @Produces( { MediaType.APPLICATION_JSON } ) 57 | @Path( "/{email}" ) 58 | @GET 59 | public Person getPeople( @PathParam( "email" ) final String email ) { 60 | return peopleService.getByEmail( email ); 61 | } 62 | } 63 | ``` 64 | 65 | The **[maven plugin](java2typescript-maven-plugin)** will produce the following typescript definition file : 66 | 67 | ```typescript 68 | export module People { 69 | 70 | export interface PeopleRestService { 71 | getPeopleList(page: number): Person[]; 72 | getPeople(email: string): Person; 73 | } 74 | 75 | export interface Person { 76 | email: string; 77 | firstName: string; 78 | lastName: string; 79 | } 80 | 81 | export var rootUrl: string; 82 | export var peopleRestService: PeopleRestService; 83 | export var adapter: (httpMethod: string, path: string, getParams: Object, postParams: Object, body: any)=> void; 84 | } 85 | ``` 86 | 87 | The module **People** contains both the definitions of the DTO **Person** and the service **PeopleRestService**. It also provides 3 properties : 88 | * **rootURL** : URL of the service : Should be set before usage 89 | * **peopleRESTService** : An instance of the service 90 | * **adapter** : An adapter for REST service call. Set to Jquery adapter by default. 91 | 92 | Then, in your application, you can call the service like so: 93 | ```typescript 94 | /// 95 | import p = People; 96 | import Person = p.Person; 97 | import prs = p.peopleRestService; 98 | 99 | p.rootUrl = "http://someurl/root/"; 100 | 101 | var personList : Person[] = prs.getPeopleList(1); 102 | var onePerson : Person = prs.getPeople("rrr@eee.com"); 103 | 104 | ``` 105 | 106 | Don't forget to import the generated file **People.js** in the final HTML page. 107 | 108 | 109 | ### Installation 110 | 111 | To install the library using Maven, add the [JitPack](https://jitpack.io/) repository and java2typescript dependency: 112 | 113 | ```xml 114 | ... 115 | 116 | 117 | jitpack.io 118 | https://jitpack.io 119 | 120 | 121 | ... 122 | 123 | 124 | com.github.raphaeljolivet.java2typescript 125 | java2typescript-maven-plugin 126 | v0.3.1 127 | 128 | 129 | ... 130 | ``` 131 | 132 | > Note, artifacts for this project are built automatically by [JitPack](https://jitpack.io/docs/#how-to) based on the github repository. 133 | 134 | > Note, if You are only interested in generating TypeScript definitions from Java classes, You can use `java2typescript-jackson` instead of `java2typescript-maven-plugin` as the artifact id. 135 | 136 | > Note, version can be replaced with 137 | * either any [released version of this project](../../releases) ([![Release](https://img.shields.io/github/release/raphaeljolivet/java2typescript.svg?label=latest release is)](https://jitpack.io/#raphaeljolivet/java2typescript)) 138 | * or any [git tag of this project](../../tags) 139 | * or any [git commit hash](../../commits/master) 140 | * or with `master-SNAPSHOT` - to indicate the latest commit of master branch (NB! Dependency managers, such as Maven cache SNAPSHOTs by default, see [JitPack documentation](https://jitpack.io/docs/#snapshots)) 141 | 142 | 143 | # Licence 144 | 145 | This project is licenced under the [Apache v2.0 Licence](http://www.apache.org/licenses/LICENSE-2.0.html) 146 | 147 | 148 | # Credits 149 | 150 | Jackson module is inspired from the [jsonSchema module](https://github.com/FasterXML/jackson-module-jsonSchema) 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /img/j2ts-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphaeljolivet/java2typescript/5e3921b674bfb03ba9ac042238a8db0b9b17ca3a/img/j2ts-workflow.png -------------------------------------------------------------------------------- /java2typescript-jackson/pom.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 4.0.0 18 | 19 | com.github.raphaeljolivet.java2typescript 20 | java2typescript 21 | v0.3.2-SNAPSHOT 22 | 23 | java2typescript-jackson 24 | java2typescript jackson module 25 | 26 | Extension Module for Jackson to provide generation of TypeScript definition file from Java class definition 27 | 28 | 29 | 30 | raphael.jolivet 31 | Raphael Jolivet 32 | raphael.jolivet@gmail.com 33 | 34 | 35 | 36 | 2.6.4 37 | github 38 | 39 | 40 | 41 | 42 | com.fasterxml.jackson.core 43 | jackson-annotations 44 | ${jackson.core.version} 45 | 46 | 47 | com.fasterxml.jackson.core 48 | jackson-core 49 | ${jackson.core.version} 50 | 51 | 52 | com.fasterxml.jackson.core 53 | jackson-databind 54 | ${jackson.core.version} 55 | 56 | 57 | 58 | com.google.guava 59 | guava 60 | 15.0 61 | test 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/Configuration.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module; 2 | 3 | import java.beans.Transient; 4 | import java.lang.reflect.Method; 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import java2typescript.jackson.module.conf.typename.SimpleJacksonTSTypeNamingStrategy; 12 | import java2typescript.jackson.module.conf.typename.TSTypeNamingStrategy; 13 | import java2typescript.jackson.module.grammar.ArrayType; 14 | import java2typescript.jackson.module.grammar.base.AbstractType; 15 | 16 | public class Configuration { 17 | private Map customTypes = Collections.emptyMap(); 18 | private List ignoredMethodNames = new ArrayList(); 19 | private TSTypeNamingStrategy namingStrategy = new SimpleJacksonTSTypeNamingStrategy(); 20 | 21 | public Map getCustomTypes() { 22 | return customTypes; 23 | } 24 | 25 | public Configuration addType(Class klass, AbstractType tsType) { 26 | addType(klass.getName(), tsType); 27 | addArrayType(klass, tsType); 28 | return this; 29 | } 30 | 31 | public void addArrayType(Class klass, AbstractType tsType) { 32 | addType("[L" + klass.getName() + ";", new ArrayType(tsType)); 33 | } 34 | 35 | public void addType(String className, AbstractType tsType) { 36 | Map tmp = new HashMap(); 37 | tmp.putAll(customTypes); 38 | tmp.put(className, tsType); 39 | customTypes = Collections.unmodifiableMap(tmp); 40 | } 41 | 42 | public void addIngoredMethod(String name) { 43 | ignoredMethodNames.add(name); 44 | } 45 | 46 | public boolean isIgnoredMethod(Method method) { 47 | if (method.getAnnotation(Transient.class) != null) { 48 | return true; 49 | } 50 | return isIgnoredMethod(method.getName()); 51 | } 52 | 53 | private boolean isIgnoredMethod(String name) { 54 | return ignoredMethodNames.contains(name); 55 | } 56 | 57 | public TSTypeNamingStrategy getNamingStrategy() { 58 | return namingStrategy; 59 | } 60 | 61 | public void setNamingStrategy(TSTypeNamingStrategy namingStrategy) { 62 | this.namingStrategy = namingStrategy; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/DefinitionGenerator.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module; 17 | 18 | import java.util.Collection; 19 | 20 | import com.fasterxml.jackson.databind.JavaType; 21 | import com.fasterxml.jackson.databind.JsonMappingException; 22 | import com.fasterxml.jackson.databind.ObjectMapper; 23 | import com.fasterxml.jackson.databind.type.SimpleType; 24 | 25 | import java2typescript.jackson.module.grammar.Module; 26 | import java2typescript.jackson.module.grammar.TypeDeclarationType; 27 | import java2typescript.jackson.module.grammar.base.AbstractType; 28 | import java2typescript.jackson.module.visitors.TSJsonFormatVisitorWrapper; 29 | 30 | /** 31 | * Main class that generates a TypeScript grammar tree (a Module), out of a 32 | * class, together with a {@link ObjectMapper} 33 | */ 34 | public class DefinitionGenerator { 35 | 36 | private final ObjectMapper mapper; 37 | 38 | public DefinitionGenerator(ObjectMapper mapper) { 39 | this.mapper = mapper; 40 | } 41 | 42 | /** 43 | * @param module 44 | * Module to be filled with named types (classes, enums, ...) 45 | * @param classes 46 | * Class for which generating definition 47 | * @throws JsonMappingException 48 | */ 49 | public Module generateTypeScript(String moduleName, Collection> classes, Configuration conf) 50 | throws JsonMappingException { 51 | if(conf == null) { 52 | conf = new Configuration(); 53 | } 54 | 55 | Module module = new Module(moduleName); 56 | TSJsonFormatVisitorWrapper visitor = new TSJsonFormatVisitorWrapper(module, conf); 57 | 58 | for (Class clazz : classes) { 59 | AbstractType customType = conf.getCustomTypes().get(clazz.getName()); 60 | if(customType != null && customType instanceof TypeDeclarationType) { 61 | // When the class is registered as TypeDeclarationType, then ... 62 | String tsTypeName = conf.getNamingStrategy().getName(SimpleType.construct(clazz)); 63 | // ... add that type to the module ... 64 | module.getNamedTypes().put(tsTypeName, (TypeDeclarationType)customType); 65 | // ... instead of inspecting class body 66 | continue; 67 | } 68 | mapper.acceptJsonFormatVisitor(clazz, visitor); 69 | } 70 | return module; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/StaticFieldExporter.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014 Florian Benz 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module; 17 | 18 | import java.lang.reflect.Field; 19 | import java.util.List; 20 | 21 | import java2typescript.jackson.module.grammar.AnyType; 22 | import java2typescript.jackson.module.grammar.ArrayType; 23 | import java2typescript.jackson.module.grammar.BooleanType; 24 | import java2typescript.jackson.module.grammar.EnumType; 25 | import java2typescript.jackson.module.grammar.Module; 26 | import java2typescript.jackson.module.grammar.NumberType; 27 | import java2typescript.jackson.module.grammar.StaticClassType; 28 | import java2typescript.jackson.module.grammar.StringType; 29 | import java2typescript.jackson.module.grammar.base.AbstractType; 30 | import java2typescript.jackson.module.grammar.base.Value; 31 | import java2typescript.jackson.module.visitors.TSJsonFormatVisitorWrapper; 32 | 33 | import com.fasterxml.jackson.databind.type.SimpleType; 34 | 35 | public class StaticFieldExporter { 36 | private static final String CLASS_NAME_EXTENSION = "Static"; 37 | 38 | private final Module module; 39 | private final TSJsonFormatVisitorWrapper tsJsonFormatVisitorWrapper; 40 | 41 | public StaticFieldExporter(Module module, Configuration conf) { 42 | this.module = module; 43 | if(conf == null) { 44 | conf = new Configuration(); 45 | } 46 | tsJsonFormatVisitorWrapper = new TSJsonFormatVisitorWrapper(module, conf); 47 | } 48 | 49 | /** @deprecated - use constructor and instance method instead */ 50 | @Deprecated 51 | public static void export(Module module, List> classesToConvert) { 52 | new StaticFieldExporter(module, null).export(classesToConvert); 53 | } 54 | 55 | public void export(List> classesToConvert) 56 | throws IllegalArgumentException { 57 | for (Class clazz : classesToConvert) { 58 | if (clazz.isEnum()) { 59 | continue; 60 | } 61 | StaticClassType staticClass = new StaticClassType(clazz.getSimpleName() 62 | + CLASS_NAME_EXTENSION); 63 | 64 | Field[] declaredFields = clazz.getDeclaredFields(); 65 | for (Field field : declaredFields) { 66 | if (isPublicStaticFinal(field.getModifiers())) { 67 | Value value; 68 | try { 69 | value = constructValue(module, field.getType(), field.get(null)); 70 | } 71 | catch (IllegalAccessException e) { 72 | throw new RuntimeException("Failed to get value of field " + field, e); 73 | } 74 | if (value != null) { 75 | staticClass.getStaticFields().put(field.getName(), value); 76 | } 77 | } 78 | } 79 | if (staticClass.getStaticFields().size() > 0) { 80 | module.getNamedTypes().put(staticClass.getName(), staticClass); 81 | } 82 | } 83 | } 84 | 85 | private boolean isPublicStaticFinal(final int modifiers) { 86 | return java.lang.reflect.Modifier.isPublic(modifiers) 87 | && java.lang.reflect.Modifier.isStatic(modifiers) 88 | && java.lang.reflect.Modifier.isFinal(modifiers); 89 | } 90 | 91 | private Value constructValue(Module module, Class type, Object rawValue) 92 | throws IllegalArgumentException, IllegalAccessException { 93 | if (type == boolean.class) { 94 | return new Value(BooleanType.getInstance(), rawValue); 95 | } else if (type == int.class) { 96 | return new Value(NumberType.getInstance(), rawValue); 97 | } else if (type == double.class) { 98 | return new Value(NumberType.getInstance(), rawValue); 99 | } else if (type == String.class) { 100 | return new Value(StringType.getInstance(), "'" + (String) rawValue + "'"); 101 | } else if (type.isEnum()) { 102 | final EnumType enumType = tsJsonFormatVisitorWrapper.parseEnumOrGetFromCache(module, 103 | SimpleType.construct(type)); 104 | return new Value(enumType, enumType.getName() + "." + rawValue); 105 | } else if (type.isArray()) { 106 | final Class componentType = type.getComponentType(); 107 | final Object[] array; 108 | if (componentType == boolean.class) { 109 | boolean[] tmpArray = (boolean[]) rawValue; 110 | array = new Boolean[tmpArray.length]; 111 | for (int i = 0; i < array.length; i++) { 112 | array[i] = Boolean.valueOf(tmpArray[i]); 113 | } 114 | } else if (componentType == int.class) { 115 | int[] tmpArray = (int[]) rawValue; 116 | array = new Integer[tmpArray.length]; 117 | for (int i = 0; i < array.length; i++) { 118 | array[i] = Integer.valueOf(tmpArray[i]); 119 | } 120 | } else if (componentType == double.class) { 121 | double[] tmpArray = (double[]) rawValue; 122 | array = new Double[tmpArray.length]; 123 | for (int i = 0; i < array.length; i++) { 124 | array[i] = Double.valueOf(tmpArray[i]); 125 | } 126 | } else { 127 | array = (Object[]) rawValue; 128 | } 129 | final StringBuilder arrayValues = new StringBuilder(); 130 | arrayValues.append("[ "); 131 | for (int i = 0; i < array.length; i++) { 132 | arrayValues.append(constructValue(module, componentType, array[i]).getValue()); 133 | if (i < array.length - 1) { 134 | arrayValues.append(", "); 135 | } 136 | } 137 | arrayValues.append(" ]"); 138 | return new Value(new ArrayType(typeScriptTypeFromJavaType(module, componentType)), 139 | arrayValues.toString()); 140 | } 141 | return null; 142 | } 143 | 144 | private AbstractType typeScriptTypeFromJavaType(Module module, Class type) { 145 | if (type == boolean.class) { 146 | return BooleanType.getInstance(); 147 | } else if (type == int.class) { 148 | return NumberType.getInstance(); 149 | } else if (type == double.class) { 150 | return NumberType.getInstance(); 151 | } else if (type == String.class) { 152 | return StringType.getInstance(); 153 | } else if (type.isEnum()) { 154 | return tsJsonFormatVisitorWrapper.parseEnumOrGetFromCache(module, SimpleType 155 | .construct(type)); 156 | } else if (type.isArray()) { 157 | return new ArrayType(AnyType.getInstance()); 158 | } 159 | throw new UnsupportedOperationException(); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/conf/typename/SimpleJacksonTSTypeNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.conf.typename; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import com.fasterxml.jackson.databind.JavaType; 5 | 6 | /** 7 | * If Java class/enum is annotated with {@link JsonTypeName}, then annotation value is used, otherwise {@link Class#getSimpleName()} 8 | */ 9 | public class SimpleJacksonTSTypeNamingStrategy implements TSTypeNamingStrategy { 10 | 11 | public String getName(JavaType type) { 12 | Class rawClass = type.getRawClass(); 13 | JsonTypeName typeName = rawClass.getAnnotation(JsonTypeName.class); 14 | if (typeName != null) { 15 | return typeName.value(); 16 | } 17 | else { 18 | return getName(rawClass); 19 | } 20 | } 21 | 22 | protected String getName(Class rawClass) { 23 | return rawClass.getSimpleName(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/conf/typename/TSTypeNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.conf.typename; 2 | 3 | import com.fasterxml.jackson.databind.JavaType; 4 | 5 | /** 6 | * Used to detect TypeScript type name based on given Java type 7 | */ 8 | public interface TSTypeNamingStrategy { 9 | 10 | /** 11 | * @return name of the TypeScript class corresponding to Java class 12 | */ 13 | String getName(JavaType type); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/conf/typename/WithEnclosingClassTSTypeNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.conf.typename; 2 | 3 | public class WithEnclosingClassTSTypeNamingStrategy extends SimpleJacksonTSTypeNamingStrategy { 4 | 5 | @Override 6 | public String getName(Class rawClass) { 7 | String className = rawClass.getName(); 8 | return className.substring(className.lastIndexOf('.') + 1); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/AnyType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java2typescript.jackson.module.grammar.base.AbstractPrimitiveType; 19 | 20 | public class AnyType extends AbstractPrimitiveType { 21 | 22 | static private AnyType instance = new AnyType(); 23 | 24 | static public AnyType getInstance() { 25 | return instance; 26 | } 27 | 28 | private AnyType() { 29 | super("any"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/ArrayType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java.io.IOException; 19 | import java.io.Writer; 20 | import java2typescript.jackson.module.grammar.base.AbstractType; 21 | 22 | 23 | public class ArrayType extends AbstractType { 24 | private AbstractType itemType; 25 | 26 | public ArrayType() { 27 | } 28 | 29 | public ArrayType(AbstractType aType) { 30 | itemType = aType; 31 | } 32 | 33 | @Override 34 | public void write(Writer writer) throws IOException { 35 | itemType.write(writer); 36 | writer.write("[]"); 37 | } 38 | 39 | public void setItemType(AbstractType itemType) { 40 | this.itemType = itemType; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/BooleanType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java2typescript.jackson.module.grammar.base.AbstractPrimitiveType; 19 | 20 | public class BooleanType extends AbstractPrimitiveType { 21 | 22 | static private BooleanType instance = new BooleanType(); 23 | 24 | static public BooleanType getInstance() { 25 | return instance; 26 | } 27 | 28 | private BooleanType() { 29 | super("boolean"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/ClassType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import static java.lang.String.format; 19 | 20 | import java.io.IOException; 21 | import java.io.Writer; 22 | import java.util.ArrayList; 23 | import java.util.Collection; 24 | import java.util.Collections; 25 | import java.util.LinkedHashMap; 26 | import java.util.List; 27 | import java.util.Map; 28 | import java.util.Map.Entry; 29 | import java.util.Set; 30 | 31 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 32 | import java2typescript.jackson.module.grammar.base.AbstractType; 33 | import java2typescript.jackson.module.writer.SortUtil; 34 | import java2typescript.jackson.module.writer.WriterPreferences; 35 | 36 | public class ClassType extends AbstractNamedType { 37 | 38 | private Map fields = new LinkedHashMap(); 39 | 40 | private Map methods = new LinkedHashMap(); 41 | 42 | static private ClassType objectType = new ClassType("Object"); 43 | 44 | /** Root Object class */ 45 | static public ClassType getObjectClass() { 46 | return objectType; 47 | } 48 | 49 | public ClassType(String className) { 50 | super(className); 51 | } 52 | 53 | @Override 54 | public void writeDefInternal(Writer writer, WriterPreferences preferences) throws IOException { 55 | writer.write(format("interface %s {\n", name)); 56 | preferences.increaseIndentation(); 57 | Collection> fieldsEntrySet = fields.entrySet(); 58 | Collection methodsKeySet = methods.keySet(); 59 | if(preferences.isSort()) { 60 | fieldsEntrySet = SortUtil.sortEntriesByKey(fieldsEntrySet); 61 | methodsKeySet = SortUtil.sort(methodsKeySet); 62 | } 63 | for (Entry entry : fieldsEntrySet) { 64 | writer.write(format("%s%s: ", preferences.getIndentation(), entry.getKey())); 65 | entry.getValue().write(writer); 66 | writer.write(";\n"); 67 | } 68 | for (String methodName : methodsKeySet) { 69 | writer.write(preferences.getIndentation() + methodName); 70 | this.methods.get(methodName).writeNonLambda(writer); 71 | writer.write(";\n"); 72 | } 73 | preferences.decreaseIndention(); 74 | writer.write(preferences.getIndentation() + "}"); 75 | } 76 | 77 | public Map getFields() { 78 | return fields; 79 | } 80 | 81 | public void setFields(Map fields) { 82 | this.fields = fields; 83 | } 84 | 85 | public Map getMethods() { 86 | return methods; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/EnumType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import static java.lang.String.format; 19 | 20 | import java.io.IOException; 21 | import java.io.Writer; 22 | import java.util.ArrayList; 23 | import java.util.Collections; 24 | import java.util.List; 25 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 26 | import java2typescript.jackson.module.writer.WriterPreferences; 27 | 28 | 29 | public class EnumType extends AbstractNamedType { 30 | 31 | private List values = new ArrayList(); 32 | 33 | public EnumType(String className) { 34 | super(className); 35 | } 36 | 37 | @Override 38 | public void writeDefInternal(Writer writer, WriterPreferences preferences) throws IOException { 39 | writer.write(format("enum %s {\n", name)); 40 | preferences.increaseIndentation(); 41 | if(preferences.isSort()) { 42 | Collections.sort(values); 43 | } 44 | for (String value : values) { 45 | writer.write(format("%s%s,\n", preferences.getIndentation(), value)); 46 | } 47 | preferences.decreaseIndention(); 48 | writer.write(preferences.getIndentation() + "}"); 49 | } 50 | 51 | public List getValues() { 52 | return values; 53 | } 54 | 55 | public void setValues(List values) { 56 | this.values = values; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/FunctionType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java.io.IOException; 19 | import java.io.Writer; 20 | import java.util.LinkedHashMap; 21 | import java.util.Map.Entry; 22 | import java2typescript.jackson.module.grammar.base.AbstractType; 23 | 24 | public class FunctionType extends AbstractType { 25 | 26 | private LinkedHashMap parameters = new LinkedHashMap(); 27 | 28 | private AbstractType resultType; 29 | 30 | /** By default, printed as lambda function type (with =>) */ 31 | @Override 32 | public void write(Writer writer) throws IOException { 33 | write(writer, true); 34 | } 35 | 36 | /** Write as non lambda : func(a:string) : string */ 37 | public void writeNonLambda(Writer writer) throws IOException { 38 | write(writer, false); 39 | } 40 | 41 | private void write(Writer writer, boolean lambdaSyntax) throws IOException { 42 | writer.write("("); 43 | int i = 1; 44 | for (Entry entry : parameters.entrySet()) { 45 | writer.write(entry.getKey()); 46 | writer.write(": "); 47 | entry.getValue().write(writer); 48 | if (i < parameters.size()) { 49 | writer.write(", "); 50 | } 51 | i++; 52 | } 53 | writer.write(")" + (lambdaSyntax ? "=> " : ": ")); 54 | resultType.write(writer); 55 | } 56 | 57 | public LinkedHashMap getParameters() { 58 | return parameters; 59 | } 60 | 61 | public AbstractType getResultType() { 62 | return resultType; 63 | } 64 | 65 | public void setResultType(AbstractType resultType) { 66 | this.resultType = resultType; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/MapType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java.io.IOException; 19 | import java.io.Writer; 20 | import java2typescript.jackson.module.grammar.base.AbstractType; 21 | 22 | 23 | public class MapType extends AbstractType { 24 | private AbstractType valueType; 25 | private AbstractType keyType; 26 | 27 | public MapType() { 28 | } 29 | 30 | @Override 31 | public void write(Writer writer) throws IOException { 32 | // TODO: only use this "key in " syntax when useStringLiteralTypeForEnums is enabled. 33 | if (keyType instanceof EnumType) { 34 | writer.write("{ [key in "); 35 | keyType.write(writer); 36 | writer.write(" ] ? : "); 37 | } else { 38 | writer.write("{ [key: "); 39 | keyType.write(writer); 40 | writer.write(" ]: "); 41 | } 42 | 43 | valueType.write(writer); 44 | writer.write(";}"); 45 | } 46 | 47 | public AbstractType getValueType() { 48 | return valueType; 49 | } 50 | 51 | public void setValueType(AbstractType valueType) { 52 | this.valueType = valueType; 53 | } 54 | 55 | public AbstractType getKeyType() { 56 | return keyType; 57 | } 58 | 59 | public void setKeyType(AbstractType keyType) { 60 | this.keyType = keyType; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/Module.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java.io.IOException; 19 | import java.io.Writer; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 24 | import java2typescript.jackson.module.grammar.base.AbstractType; 25 | import java2typescript.jackson.module.writer.InternalModuleFormatWriter; 26 | 27 | public class Module { 28 | 29 | private String name; 30 | 31 | private Map namedTypes = new HashMap(); 32 | 33 | private Map vars = new HashMap(); 34 | 35 | public Module() { 36 | } 37 | 38 | public Module(String name) { 39 | this.name = name; 40 | } 41 | 42 | public Map getNamedTypes() { 43 | return namedTypes; 44 | } 45 | 46 | public Map getVars() { 47 | return vars; 48 | } 49 | 50 | public void setName(String name) { 51 | this.name = name; 52 | } 53 | 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | public void write(Writer writer) throws IOException { 59 | new InternalModuleFormatWriter().write(this, writer); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/NullType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java2typescript.jackson.module.grammar.base.AbstractPrimitiveType; 19 | 20 | public class NullType extends AbstractPrimitiveType { 21 | 22 | static private NullType instance = new NullType(); 23 | 24 | static public NullType getInstance() { 25 | return instance; 26 | } 27 | 28 | private NullType() { 29 | super("null"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/NumberType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java2typescript.jackson.module.grammar.base.AbstractPrimitiveType; 19 | 20 | public class NumberType extends AbstractPrimitiveType { 21 | 22 | static private NumberType instance = new NumberType(); 23 | 24 | static public NumberType getInstance() { 25 | return instance; 26 | } 27 | 28 | private NumberType() { 29 | super("number"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/StaticClassType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet, 2014 Florian Benz 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import static java.lang.String.format; 19 | 20 | import java.io.IOException; 21 | import java.io.Writer; 22 | import java.util.Collection; 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | import java.util.Map.Entry; 26 | 27 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 28 | import java2typescript.jackson.module.grammar.base.Value; 29 | import java2typescript.jackson.module.writer.SortUtil; 30 | import java2typescript.jackson.module.writer.WriterPreferences; 31 | 32 | public class StaticClassType extends AbstractNamedType { 33 | 34 | private Map fields = new HashMap(); 35 | 36 | public StaticClassType(String className) { 37 | super(className); 38 | } 39 | 40 | @Override 41 | public void writeDefInternal(Writer writer, WriterPreferences prefs) throws IOException { 42 | writer.write(format("class %s {\n", name)); 43 | prefs.increaseIndentation(); 44 | Collection> fieldsEntrySet = fields.entrySet(); 45 | if(prefs.isSort()) { 46 | fieldsEntrySet = SortUtil.sortEntriesByKey(fieldsEntrySet); 47 | } 48 | for (Entry entry : fieldsEntrySet) { 49 | writer.write(format("%sstatic %s: ", prefs.getIndentation(), entry.getKey())); 50 | entry.getValue().getType().write(writer); 51 | writer.write(" = "); 52 | writer.write(entry.getValue().getValue().toString()); 53 | writer.write(";\n"); 54 | } 55 | prefs.decreaseIndention(); 56 | writer.write(prefs.getIndentation() + "}"); 57 | } 58 | 59 | public Map getStaticFields() { 60 | return fields; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/StringType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java2typescript.jackson.module.grammar.base.AbstractPrimitiveType; 19 | 20 | public class StringType extends AbstractPrimitiveType { 21 | 22 | static private StringType instance = new StringType(); 23 | 24 | static public StringType getInstance() { 25 | return instance; 26 | } 27 | 28 | private StringType() { 29 | super("string"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/TypeDeclarationType.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.grammar; 2 | 3 | import static java.lang.String.format; 4 | 5 | import java.io.IOException; 6 | import java.io.Writer; 7 | 8 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 9 | import java2typescript.jackson.module.writer.WriterPreferences; 10 | 11 | /** 12 | * {@link java2typescript.jackson.module.grammar.base.AbstractType} that has name, like classes/interfaces, 13 | * but instead of body the type has declared value. 14 | *

15 | * For example 16 | * `type NumberOrString = number | string` 17 | * that can be expressed with 18 | *

19 | * `new TypeDeclarationType("NumberOrString", "number | string")` 20 | * 21 | * @author Ats Uiboupin 22 | */ 23 | public class TypeDeclarationType extends AbstractNamedType { 24 | 25 | private String typeScriptType; 26 | 27 | public TypeDeclarationType(String className, String typeScriptType) { 28 | super(className); 29 | this.typeScriptType = typeScriptType; 30 | } 31 | 32 | @Override 33 | public void writeDefInternal(Writer writer, WriterPreferences preferences) throws IOException { 34 | // TODO separate writer for this type 35 | writer.write(format("type %s = %s;", name, typeScriptType)); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/VoidType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar; 17 | 18 | import java2typescript.jackson.module.grammar.base.AbstractPrimitiveType; 19 | 20 | public class VoidType extends AbstractPrimitiveType { 21 | 22 | static private VoidType instance = new VoidType(); 23 | 24 | static public VoidType getInstance() { 25 | return instance; 26 | } 27 | 28 | private VoidType() { 29 | super("void"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/base/AbstractNamedType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar.base; 17 | 18 | import java.io.IOException; 19 | import java.io.Writer; 20 | 21 | import java2typescript.jackson.module.writer.WriterPreferences; 22 | 23 | /** Type referenced by its name and capable of writing its own definition */ 24 | abstract public class AbstractNamedType extends AbstractType { 25 | 26 | protected final String name; 27 | 28 | public AbstractNamedType(String className) { 29 | this.name = className; 30 | } 31 | 32 | @Override 33 | public void write(Writer writer) throws IOException { 34 | writer.write(name); 35 | } 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public void writeDef(Writer writer, WriterPreferences preferences) throws IOException { 42 | if(!preferences.hasCustomWriter(this)) { 43 | writeDefInternal(writer, preferences); 44 | } else { 45 | preferences.writeDef(this, writer); 46 | } 47 | } 48 | 49 | abstract public void writeDefInternal(Writer writer, WriterPreferences preferences) throws IOException; 50 | } 51 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/base/AbstractPrimitiveType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar.base; 17 | 18 | import java.io.IOException; 19 | import java.io.Writer; 20 | 21 | abstract public class AbstractPrimitiveType extends AbstractType { 22 | 23 | private String token; 24 | 25 | public AbstractPrimitiveType(String token) { 26 | this.token = token; 27 | } 28 | 29 | @Override 30 | public void write(Writer writer) throws IOException { 31 | writer.write(token); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/base/AbstractType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar.base; 17 | 18 | import java.io.IOException; 19 | import java.io.Writer; 20 | 21 | public abstract class AbstractType { 22 | public abstract void write(Writer writer) throws IOException; 23 | } 24 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/grammar/base/Value.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014 Florian Benz 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.grammar.base; 17 | 18 | public class Value { 19 | private AbstractType type; 20 | 21 | private Object value; 22 | 23 | public Value(AbstractType type, Object value) { 24 | this.type = type; 25 | this.value = value; 26 | } 27 | 28 | public AbstractType getType() { 29 | return type; 30 | } 31 | 32 | public Object getValue() { 33 | return value; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/ABaseTSJsonFormatVisitor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.visitors; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | import java2typescript.jackson.module.grammar.Module; 21 | import java2typescript.jackson.module.grammar.base.AbstractType; 22 | 23 | import com.fasterxml.jackson.databind.JavaType; 24 | import com.fasterxml.jackson.databind.SerializerProvider; 25 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWithSerializerProvider; 26 | 27 | import java2typescript.jackson.module.Configuration; 28 | 29 | /** 30 | * Chained providers with a root parent holder keeping a map of already 31 | * compiuted types, and 32 | */ 33 | public abstract class ABaseTSJsonFormatVisitor implements 34 | JsonFormatVisitorWithSerializerProvider { 35 | 36 | private final ABaseTSJsonFormatVisitor parentHolder; 37 | 38 | protected T type; 39 | 40 | private SerializerProvider serializerProvider; 41 | 42 | private Module module; 43 | 44 | private Map computedTypes; 45 | 46 | protected final Configuration conf; 47 | 48 | public ABaseTSJsonFormatVisitor(ABaseTSJsonFormatVisitor parentHolder, Configuration conf) { 49 | this.parentHolder = parentHolder; 50 | this.conf = conf; 51 | } 52 | 53 | public ABaseTSJsonFormatVisitor(Module module, Configuration conf) { 54 | this.parentHolder = null; 55 | this.module = module; 56 | this.conf = conf; 57 | } 58 | 59 | public SerializerProvider getProvider() { 60 | return (parentHolder == null) ? serializerProvider : parentHolder.getProvider(); 61 | } 62 | 63 | public void setProvider(SerializerProvider provider) { 64 | if (parentHolder != null) { 65 | parentHolder.setProvider(provider); 66 | } else { 67 | serializerProvider = provider; 68 | } 69 | } 70 | 71 | public Module getModule() { 72 | if (parentHolder == null) { 73 | return module; 74 | } else { 75 | return parentHolder.getModule(); 76 | } 77 | } 78 | 79 | public Map getComputedTypes() { 80 | if (parentHolder == null) { 81 | if (computedTypes == null) { 82 | computedTypes = new HashMap(); 83 | } 84 | return computedTypes; 85 | } else { 86 | return parentHolder.getComputedTypes(); 87 | } 88 | } 89 | 90 | public T getType() { 91 | return type; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/TSJsonAnyFormatVisitor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.visitors; 17 | 18 | import java2typescript.jackson.module.Configuration; 19 | import java2typescript.jackson.module.grammar.AnyType; 20 | 21 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonAnyFormatVisitor; 22 | 23 | public class TSJsonAnyFormatVisitor extends ABaseTSJsonFormatVisitor implements JsonAnyFormatVisitor { 24 | public TSJsonAnyFormatVisitor(ABaseTSJsonFormatVisitor parentHolder, Configuration conf) { 25 | super(parentHolder, conf); 26 | type = AnyType.getInstance(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/TSJsonArrayFormatVisitor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.visitors; 17 | 18 | import java2typescript.jackson.module.Configuration; 19 | import java2typescript.jackson.module.grammar.AnyType; 20 | import java2typescript.jackson.module.grammar.ArrayType; 21 | import java2typescript.jackson.module.grammar.BooleanType; 22 | import java2typescript.jackson.module.grammar.NumberType; 23 | import java2typescript.jackson.module.grammar.StringType; 24 | import java2typescript.jackson.module.grammar.base.AbstractType; 25 | 26 | import com.fasterxml.jackson.databind.JavaType; 27 | import com.fasterxml.jackson.databind.JsonMappingException; 28 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor; 29 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; 30 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable; 31 | 32 | public class TSJsonArrayFormatVisitor extends ABaseTSJsonFormatVisitor implements JsonArrayFormatVisitor { 33 | 34 | public TSJsonArrayFormatVisitor(ABaseTSJsonFormatVisitor parentHolder, Configuration conf) { 35 | super(parentHolder, conf); 36 | type = new ArrayType(); 37 | } 38 | 39 | @Override 40 | public void itemsFormat(JsonFormatVisitable handler, JavaType elementType) throws JsonMappingException { 41 | TSJsonFormatVisitorWrapper visitorWrapper = new TSJsonFormatVisitorWrapper(this, conf); 42 | handler.acceptJsonFormatVisitor(visitorWrapper, elementType); 43 | type.setItemType(visitorWrapper.getType()); 44 | } 45 | 46 | @Override 47 | public void itemsFormat(JsonFormatTypes format) throws JsonMappingException { 48 | type.setItemType(typeScriptTypeFromJsonType(format)); 49 | } 50 | 51 | private static AbstractType typeScriptTypeFromJsonType(JsonFormatTypes type) { 52 | switch (type) { 53 | case ANY: 54 | return AnyType.getInstance(); 55 | case BOOLEAN: 56 | return BooleanType.getInstance(); 57 | case ARRAY: 58 | return new ArrayType(AnyType.getInstance()); 59 | case INTEGER: //$FALL-THROUGH$ 60 | case NUMBER: 61 | return NumberType.getInstance(); 62 | case STRING: 63 | return StringType.getInstance(); 64 | default: 65 | throw new UnsupportedOperationException(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/TSJsonBooleanFormatVisitor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.visitors; 17 | 18 | import java.util.Set; 19 | 20 | import java2typescript.jackson.module.Configuration; 21 | import java2typescript.jackson.module.grammar.BooleanType; 22 | 23 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonBooleanFormatVisitor; 24 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat; 25 | 26 | public class TSJsonBooleanFormatVisitor extends ABaseTSJsonFormatVisitor implements 27 | JsonBooleanFormatVisitor { 28 | 29 | public TSJsonBooleanFormatVisitor(ABaseTSJsonFormatVisitor parentHolder, Configuration conf) { 30 | super(parentHolder, conf); 31 | type = BooleanType.getInstance(); 32 | } 33 | 34 | @Override 35 | public void format(JsonValueFormat format) { 36 | } 37 | 38 | @Override 39 | public void enumTypes(Set enums) { 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/TSJsonMapFormatVisitor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.visitors; 17 | 18 | import static java2typescript.jackson.module.visitors.TSJsonFormatVisitorWrapper.getTSTypeForHandler; 19 | 20 | import java2typescript.jackson.module.grammar.MapType; 21 | 22 | import com.fasterxml.jackson.databind.JavaType; 23 | import com.fasterxml.jackson.databind.JsonMappingException; 24 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable; 25 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonMapFormatVisitor; 26 | 27 | import java2typescript.jackson.module.Configuration; 28 | 29 | 30 | public class TSJsonMapFormatVisitor extends ABaseTSJsonFormatVisitor implements JsonMapFormatVisitor { 31 | 32 | public TSJsonMapFormatVisitor(ABaseTSJsonFormatVisitor parentHolder, Configuration conf) { 33 | super(parentHolder, conf); 34 | type = new MapType(); 35 | } 36 | 37 | @Override 38 | public void keyFormat(JsonFormatVisitable handler, JavaType keyType) throws JsonMappingException { 39 | type.setKeyType(getTSTypeForHandler(this, handler, keyType, conf)); 40 | } 41 | 42 | @Override 43 | public void valueFormat(JsonFormatVisitable handler, JavaType valueType) throws JsonMappingException { 44 | type.setValueType(getTSTypeForHandler(this, handler, valueType, conf)); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/TSJsonNullFormatVisitor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.visitors; 17 | 18 | import java2typescript.jackson.module.Configuration; 19 | import java2typescript.jackson.module.grammar.NullType; 20 | 21 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNullFormatVisitor; 22 | 23 | public class TSJsonNullFormatVisitor extends ABaseTSJsonFormatVisitor implements JsonNullFormatVisitor { 24 | public TSJsonNullFormatVisitor(ABaseTSJsonFormatVisitor parentHolder, Configuration conf) { 25 | super(parentHolder, conf); 26 | type = NullType.getInstance(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/TSJsonNumberFormatVisitor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.visitors; 17 | 18 | import java.util.Set; 19 | 20 | import java2typescript.jackson.module.Configuration; 21 | import java2typescript.jackson.module.grammar.NumberType; 22 | 23 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor; 24 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNumberFormatVisitor; 25 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat; 26 | 27 | public class TSJsonNumberFormatVisitor extends ABaseTSJsonFormatVisitor implements JsonNumberFormatVisitor, 28 | JsonIntegerFormatVisitor { 29 | 30 | public TSJsonNumberFormatVisitor(ABaseTSJsonFormatVisitor parentHolder, Configuration conf) { 31 | super(parentHolder, conf); 32 | type = NumberType.getInstance(); 33 | } 34 | 35 | @Override 36 | public void format(JsonValueFormat format) { 37 | } 38 | 39 | @Override 40 | public void enumTypes(Set enums) { 41 | } 42 | 43 | @Override 44 | public void numberType(com.fasterxml.jackson.core.JsonParser.NumberType type) { 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/TSJsonStringFormatVisitor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module.visitors; 17 | 18 | import java.util.Set; 19 | 20 | import java2typescript.jackson.module.Configuration; 21 | import java2typescript.jackson.module.grammar.StringType; 22 | 23 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor; 24 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat; 25 | 26 | public class TSJsonStringFormatVisitor extends ABaseTSJsonFormatVisitor implements JsonStringFormatVisitor { 27 | 28 | public TSJsonStringFormatVisitor(ABaseTSJsonFormatVisitor parentHolder, Configuration conf) { 29 | super(parentHolder, conf); 30 | type = StringType.getInstance(); 31 | } 32 | 33 | @Override 34 | public void format(JsonValueFormat format) { 35 | } 36 | 37 | @Override 38 | public void enumTypes(Set enums) { 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/AmbientModuleFormatWriter.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import static java.lang.String.format; 4 | 5 | import java.io.IOException; 6 | import java.io.Writer; 7 | 8 | import java2typescript.jackson.module.grammar.Module; 9 | 10 | /** 11 | * Generates TypeScript type definitions for given module in declared module format 12 | */ 13 | public class AmbientModuleFormatWriter extends ExternalModuleFormatWriter { 14 | 15 | @Override 16 | public void write(Module module, Writer writer) throws IOException { 17 | writer.write(format("declare module %s {\n\n", module.getName())); 18 | preferences.increaseIndentation(); 19 | writeModuleContent(module, writer); 20 | preferences.decreaseIndention(); 21 | writer.write("}\n"); 22 | writer.flush(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/CustomAbstractTypeWriter.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | 6 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 7 | 8 | /** 9 | * Class implementing this interface can be used to customize how Java type is written to TypeScript 10 | * @author Ats Uiboupin 11 | */ 12 | public interface CustomAbstractTypeWriter { 13 | /** 14 | * @return true if this class should handle writing the type to {@link Writer} 15 | */ 16 | boolean accepts(AbstractNamedType type, WriterPreferences preferences); 17 | 18 | void writeDef(AbstractNamedType type, Writer writer, WriterPreferences preferences) throws IOException; 19 | } 20 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/EnumTypeToEnumPatternWriter.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | import java.util.List; 6 | 7 | import java2typescript.jackson.module.grammar.EnumType; 8 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 9 | 10 | /** 11 | * Alternative to writing Java enum type to TypeScript enum type. Usefult, if You have following goals:
12 | * 1) JavaScript object containing field of "enum" must contain enum name instead of ordinal value. This is good for several reasons: a) easy to understand JSON content b) doesn't mess things up, if enum order changes in backend.
13 | * 2) You'd still like to write TypeScript as if You were using real enums - type safety, etc.
14 | * 3) You need to use "reflection" (instanceof) to detect if field is "enum" 15 | * @author Ats Uiboupin 16 | */ 17 | public class EnumTypeToEnumPatternWriter implements CustomAbstractTypeWriter { 18 | 19 | @Override 20 | public boolean accepts(AbstractNamedType type, WriterPreferences preferences) { 21 | return type instanceof EnumType; 22 | } 23 | 24 | @Override 25 | public void writeDef(AbstractNamedType type, Writer writer, WriterPreferences preferences) throws IOException { 26 | EnumType enumType = (EnumType) type; 27 | String enumTypeName = enumType.getName(); 28 | writer.write(String.format("class %s extends EnumPatternBase {\n", enumTypeName)); 29 | preferences.increaseIndentation(); 30 | List enumConstants = enumType.getValues(); 31 | if(preferences.isSort()) { 32 | enumConstants = SortUtil.sort(enumConstants); 33 | } 34 | for (String value : enumConstants) { 35 | writer.write(String.format(preferences.getIndentation() + "static %s = new %s('%s');\n", getConstantName(value), enumTypeName, value)); 36 | } 37 | writer.write(preferences.getIndentation() + "constructor(name:string){super(name);}\n"); 38 | preferences.decreaseIndention(); 39 | writer.write(preferences.getIndentation() + "}"); 40 | } 41 | 42 | String getConstantName(String value) { 43 | // lowercase "name" is special, can cause issues with JavaScript at runtime 44 | return "name".equals(value) ? "name_" : value; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/EnumTypeToStringLiteralTypeWriter.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import static java.lang.String.format; 4 | 5 | import java.io.IOException; 6 | import java.io.Writer; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | 10 | import java2typescript.jackson.module.grammar.EnumType; 11 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 12 | 13 | /** 14 | * Another alternate way of converting Java enums. This writer will convert enums to what is known as a String Literal 15 | * Type in TypeScript (>=1.8). The advantage here is that the generated typescript definitions can be used with JSON 16 | * that has the string value of the corresponding java enum value, while still maintaining strong-typing. 17 | * More info: https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types 18 | * @author Andy Perlitch 19 | */ 20 | public class EnumTypeToStringLiteralTypeWriter implements CustomAbstractTypeWriter { 21 | 22 | private String enumConstantValuesClassSufix = "Values"; 23 | 24 | @Override 25 | public boolean accepts(AbstractNamedType type, WriterPreferences preferences) { 26 | return type instanceof EnumType; 27 | } 28 | 29 | @Override 30 | public void writeDef(AbstractNamedType type, Writer writer, WriterPreferences preferences) throws IOException { 31 | // metadata about the enum being converted 32 | EnumType enumType = (EnumType) type; 33 | String enumTypeName = enumType.getName(); 34 | List enumConstants = enumType.getValues(); 35 | 36 | writer.write(format("type %s =\n", enumTypeName)); 37 | preferences.increaseIndentation(); 38 | if(preferences.isSort()) { 39 | enumConstants = SortUtil.sort(enumConstants); 40 | } 41 | Iterator iter = enumConstants.iterator(); 42 | boolean isFirst = true; 43 | while(iter.hasNext()) { 44 | String value = iter.next(); 45 | writer.write(format("%s%s\"%s\"%s", 46 | preferences.getIndentation(), 47 | isFirst ? "" : "| ", 48 | value, 49 | iter.hasNext() ? "\n" : ";" 50 | )); 51 | isFirst = false; 52 | } 53 | preferences.decreaseIndention(); 54 | 55 | if (preferences.isConstantsForStringLiteralTypeEnums()) { 56 | writeConstants(writer, preferences, enumTypeName, enumConstants); 57 | } 58 | } 59 | 60 | private void writeConstants( 61 | Writer writer, 62 | WriterPreferences preferences, 63 | String enumTypeName, 64 | List enumConstants) throws IOException { 65 | writer.write("\n\n"); 66 | writer.write(format("export class %s {\n", enumTypeName + enumConstantValuesClassSufix)); 67 | preferences.increaseIndentation(); 68 | Iterator iter2 = enumConstants.iterator(); 69 | while(iter2.hasNext()) { 70 | String value = iter2.next(); 71 | writer.write(format("%sstatic %s: %s = \"%s\";\n", 72 | preferences.getIndentation(), 73 | getConstantName(value), 74 | enumTypeName, 75 | value 76 | )); 77 | } 78 | preferences.decreaseIndention(); 79 | writer.write(preferences.getIndentation() + "}"); 80 | } 81 | 82 | String getConstantName(String value) { 83 | // lowercase "name" is special, can cause issues with JavaScript at runtime 84 | return "name".equals(value) ? "name_" : value; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/ExternalModuleFormatWriter.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | import java.util.Collection; 6 | import java.util.Map.Entry; 7 | 8 | import java2typescript.jackson.module.grammar.EnumType; 9 | import java2typescript.jackson.module.grammar.Module; 10 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 11 | import java2typescript.jackson.module.grammar.base.AbstractType; 12 | 13 | /** 14 | * Generates TypeScript type definitions for given module in external module format 15 | */ 16 | public class ExternalModuleFormatWriter implements ModuleWriter { 17 | 18 | public WriterPreferences preferences = new WriterPreferences(); 19 | 20 | @Override 21 | public void write(Module module, Writer writer) throws IOException { 22 | writeModuleContent(module, writer); 23 | writer.flush(); 24 | } 25 | 26 | protected void writeModuleContent(Module module, Writer writer) throws IOException { 27 | Collection namedTypes = module.getNamedTypes().values(); 28 | 29 | writeEnumPatternBaseClassIfNeeded(namedTypes, writer); 30 | 31 | if (preferences.isSort()) { 32 | namedTypes = SortUtil.sortByTypeName(namedTypes); 33 | } 34 | for (AbstractNamedType type : namedTypes) { 35 | writer.write(preferences.getIndentation() + "export "); 36 | type.writeDef(writer, preferences); 37 | writer.write("\n\n"); 38 | } 39 | 40 | if (preferences.isSort()) { 41 | namedTypes = SortUtil.sortByTypeName(namedTypes); 42 | } 43 | Collection> entrySet = module.getVars().entrySet(); 44 | if (preferences.isSort()) { 45 | entrySet = SortUtil.sortEntriesByKey(entrySet); 46 | } 47 | for (Entry entry : entrySet) { 48 | writer.write(preferences.getIndentation() + "export var " + entry.getKey() + ": "); 49 | entry.getValue().write(writer); 50 | writer.write(";\n"); 51 | } 52 | } 53 | 54 | private void writeEnumPatternBaseClassIfNeeded(Collection namedTypes, Writer writer) throws IOException { 55 | if (preferences.isUseEnumPattern() && hasEnum(namedTypes)) { 56 | writeBaseEnum(writer); 57 | writer.write("\n"); 58 | } 59 | } 60 | 61 | private boolean hasEnum(Collection namedTypes) { 62 | for (AbstractNamedType type : namedTypes) { 63 | if (type instanceof EnumType) { 64 | return true; 65 | } 66 | } 67 | return false; 68 | } 69 | 70 | private void writeBaseEnum(Writer writer) throws IOException { 71 | writer.write(preferences.getIndentation() + "/** base class for implementing enums with Typesafe Enum Pattern " + 72 | "(to be able to use enum names, instead of ordinal values, in a type-safe manner) */\n"); 73 | writer.write(preferences.getIndentation() + "export class EnumPatternBase {\n"); 74 | preferences.increaseIndentation(); 75 | writer.write(preferences.getIndentation() + "constructor(public name: string){}\n"); 76 | writer.write(preferences.getIndentation() + "toString(){ return this.name; }\n"); 77 | preferences.decreaseIndention(); 78 | writer.write(preferences.getIndentation() + "}\n"); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/InternalModuleFormatWriter.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import static java.lang.String.format; 4 | 5 | import java.io.IOException; 6 | import java.io.Writer; 7 | 8 | import java2typescript.jackson.module.grammar.Module; 9 | 10 | /** 11 | * Generates TypeScript type definitions for given module in internal module format 12 | */ 13 | public class InternalModuleFormatWriter extends ExternalModuleFormatWriter { 14 | 15 | @Override 16 | public void write(Module module, Writer writer) throws IOException { 17 | writer.write(format("export module %s {\n\n", module.getName())); 18 | preferences.increaseIndentation(); 19 | writeModuleContent(module, writer); 20 | preferences.decreaseIndention(); 21 | writer.write("}\n"); 22 | writer.flush(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/ModuleWriter.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | 6 | import java2typescript.jackson.module.grammar.Module; 7 | 8 | public interface ModuleWriter { 9 | void write(Module module, Writer writer) throws IOException; 10 | } 11 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/SortUtil.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.Collections; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | import java.util.Map.Entry; 9 | 10 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 11 | 12 | public class SortUtil { 13 | 14 | public static Collection sortByTypeName(Collection namedTypes) { 15 | namedTypes = new ArrayList(namedTypes); 16 | Collections.sort((List) namedTypes, new Comparator() { 17 | @Override 18 | public int compare(AbstractNamedType o1, AbstractNamedType o2) { 19 | return o1.getName().compareTo(o2.getName()); 20 | } 21 | }); 22 | return namedTypes; 23 | } 24 | 25 | public static List> sortEntriesByKey(Collection> entrySet) { 26 | List> results = new ArrayList>(entrySet); 27 | Collections.sort(results, new Comparator>() { 28 | @Override 29 | public int compare(Entry e1, Entry e2) { 30 | return e1.getKey().compareTo(e2.getKey()); 31 | } 32 | }); 33 | return results; 34 | } 35 | 36 | public static List sort(Collection collection) { 37 | List list = new ArrayList(collection); 38 | Collections.sort(list); 39 | return list; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/main/java/java2typescript/jackson/module/writer/WriterPreferences.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.writer; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import java2typescript.jackson.module.grammar.base.AbstractNamedType; 9 | 10 | public class WriterPreferences { 11 | private String indentationStep = " "; 12 | private int indentationLevel = 0; 13 | 14 | private List customWriters = new ArrayList(); 15 | private boolean useEnumPattern; 16 | private boolean enumAsStringLiteralType = false; 17 | private boolean constantsForStringLiteralTypeEnums = false; 18 | /** sort types and vars in output */ 19 | private boolean sort; 20 | 21 | public boolean isStringLiteralTypeForEnums() { 22 | return enumAsStringLiteralType; 23 | } 24 | 25 | public void useStringLiteralTypeForEnums(boolean withConstants) { 26 | addWriter(new EnumTypeToStringLiteralTypeWriter()); 27 | this.enumAsStringLiteralType = true; 28 | this.constantsForStringLiteralTypeEnums = withConstants; 29 | } 30 | 31 | public void useStringLiteralTypeForEnums() { 32 | useStringLiteralTypeForEnums(false); 33 | } 34 | 35 | public boolean isConstantsForStringLiteralTypeEnums() { 36 | return this.constantsForStringLiteralTypeEnums; 37 | } 38 | 39 | public void useEnumPattern() { 40 | addWriter(new EnumTypeToEnumPatternWriter()); 41 | useEnumPattern = true; 42 | } 43 | 44 | public boolean isUseEnumPattern() { 45 | return useEnumPattern; 46 | } 47 | 48 | public void sort() { 49 | sort = true; 50 | } 51 | 52 | public boolean isSort() { 53 | return sort; 54 | } 55 | 56 | public void addWriter(CustomAbstractTypeWriter writer) { 57 | this.customWriters.add(writer); 58 | } 59 | 60 | public List getCustomWriters() { 61 | return customWriters; 62 | } 63 | 64 | public boolean hasCustomWriter(AbstractNamedType type) { 65 | return getCustomWriter(type) != null; 66 | } 67 | 68 | public void writeDef(AbstractNamedType type, Writer writer) throws IOException { 69 | getCustomWriter(type).writeDef(type, writer, this); 70 | } 71 | 72 | public CustomAbstractTypeWriter getCustomWriter(AbstractNamedType type) { 73 | for (CustomAbstractTypeWriter writer : customWriters) { 74 | if (writer.accepts(type, this)) { 75 | return writer; 76 | } 77 | } 78 | return null; 79 | } 80 | 81 | public String getIndentation() { 82 | StringBuilder sb = new StringBuilder(); 83 | int i = 0; 84 | while (i++ < indentationLevel) { 85 | sb.append(indentationStep); 86 | } 87 | return sb.toString(); 88 | } 89 | 90 | public void setIndentationStep(String indentation) { 91 | this.indentationStep = indentation; 92 | } 93 | 94 | public void increaseIndentation() { 95 | indentationLevel++; 96 | } 97 | 98 | public void decreaseIndention() { 99 | indentationLevel--; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/ClassWithoutFieldsTest.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module; 2 | 3 | import java.io.IOException; 4 | import java.io.StringWriter; 5 | import java.io.Writer; 6 | 7 | import org.junit.Test; 8 | 9 | import java2typescript.jackson.module.grammar.Module; 10 | import java2typescript.jackson.module.util.ExpectedOutputChecker; 11 | import java2typescript.jackson.module.util.TestUtil; 12 | import java2typescript.jackson.module.writer.ExternalModuleFormatWriter; 13 | 14 | public class ClassWithoutFieldsTest { 15 | 16 | static class ClassWithoutFields { 17 | } 18 | 19 | @Test 20 | public void classWithoutFields() throws IOException { 21 | // Arrange 22 | Module module = TestUtil.createTestModule(null, ClassWithoutFields.class); 23 | Writer out = new StringWriter(); 24 | 25 | // Act 26 | new ExternalModuleFormatWriter().write(module, out); 27 | out.close(); 28 | System.out.println(out); 29 | 30 | // Assert 31 | ExpectedOutputChecker.checkOutputFromFile(out); 32 | } 33 | 34 | @Test 35 | public void referencesClassWithoutFields() throws IOException { 36 | // Arrange 37 | @SuppressWarnings("unused") 38 | class RererencesClassWithoutFields { 39 | public ClassWithoutFields classWithoutFields; 40 | public Object javaLangObject; 41 | } 42 | Module module = TestUtil.createTestModule(null, RererencesClassWithoutFields.class); 43 | Writer out = new StringWriter(); 44 | 45 | // Act 46 | new ExternalModuleFormatWriter().write(module, out); 47 | out.close(); 48 | System.out.println(out); 49 | 50 | // Assert 51 | ExpectedOutputChecker.checkOutputFromFile(out); 52 | } 53 | 54 | @Test 55 | public void classWithOnlyMethod() throws IOException { 56 | // Arrange 57 | class ClassWithOnlyMethod { 58 | @SuppressWarnings("unused") 59 | public void onlyMethod() { 60 | } 61 | } 62 | Module module = TestUtil.createTestModule(null, ClassWithOnlyMethod.class); 63 | Writer out = new StringWriter(); 64 | 65 | // Act 66 | new ExternalModuleFormatWriter().write(module, out); 67 | out.close(); 68 | System.out.println(out); 69 | 70 | // Assert 71 | ExpectedOutputChecker.checkOutputFromFile(out); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/CustomTypeDefinitionGeneratorTest.java: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************************************* 3 | * Copyright 2013 Ats Uiboupin 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | ******************************************************************************/ 17 | package java2typescript.jackson.module; 18 | 19 | import java.io.IOException; 20 | import java.io.StringWriter; 21 | import java.io.Writer; 22 | import java.util.Date; 23 | 24 | import org.junit.Test; 25 | 26 | import java2typescript.jackson.module.grammar.Module; 27 | import java2typescript.jackson.module.grammar.TypeDeclarationType; 28 | import java2typescript.jackson.module.grammar.base.AbstractPrimitiveType; 29 | import java2typescript.jackson.module.util.ExpectedOutputChecker; 30 | import java2typescript.jackson.module.util.TestUtil; 31 | import java2typescript.jackson.module.writer.ExternalModuleFormatWriter; 32 | 33 | public class CustomTypeDefinitionGeneratorTest { 34 | 35 | class TestClass { 36 | public CustomDate customDate; 37 | public CustomDate[] customDateArray; 38 | } 39 | 40 | public class CustomDate { 41 | public Date value; 42 | } 43 | 44 | public class LongValueAddedDirectlyToModule { 45 | public Long value; 46 | } 47 | 48 | public class Unused { 49 | public Long value; 50 | } 51 | 52 | public static class DateType extends AbstractPrimitiveType { 53 | 54 | static private DateType instance = new DateType(); 55 | 56 | static public DateType getInstance() { 57 | return instance; 58 | } 59 | 60 | private DateType() { 61 | super("Date"); 62 | } 63 | } 64 | 65 | @Test 66 | public void classWithCustomTypeFields() throws IOException { 67 | // Arrange 68 | Configuration conf = new Configuration().addType(CustomDate.class, DateType.getInstance()); 69 | Module module = TestUtil.createTestModule(conf, TestClass.class); 70 | Writer out = new StringWriter(); 71 | 72 | // Act 73 | new ExternalModuleFormatWriter().write(module, out); 74 | out.close(); 75 | System.out.println(out); 76 | 77 | // Assert 78 | ExpectedOutputChecker.checkOutputFromFile(out); 79 | } 80 | 81 | @Test 82 | public void declareTypeInsteadOfEmittingInterface() throws IOException { 83 | // Arrange 84 | Configuration conf = new Configuration() 85 | .addType(CustomDate.class, new TypeDeclarationType("DateStringOrNumber", "string | number")) 86 | .addType(LongValueAddedDirectlyToModule.class, new TypeDeclarationType("NumericValue", "number")) 87 | .addType(Unused.class, new TypeDeclarationType("Unused", "shouldNotBeEmitted")); 88 | Module module = TestUtil.createTestModule(conf, TestClass.class, LongValueAddedDirectlyToModule.class); 89 | Writer out = new StringWriter(); 90 | 91 | // Act 92 | new ExternalModuleFormatWriter().write(module, out); 93 | out.close(); 94 | System.out.println(out); 95 | 96 | // Assert 97 | ExpectedOutputChecker.checkOutputFromFile(out); 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/DefinitionGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module; 17 | 18 | import java.io.IOException; 19 | import java.io.StringWriter; 20 | import java.io.Writer; 21 | import java.util.ArrayList; 22 | import java.util.Collection; 23 | import java.util.Map; 24 | 25 | import java2typescript.jackson.module.writer.AmbientModuleFormatWriter; 26 | import org.junit.Test; 27 | 28 | import com.fasterxml.jackson.annotation.JsonTypeName; 29 | import com.fasterxml.jackson.databind.JsonMappingException; 30 | 31 | import java2typescript.jackson.module.grammar.Module; 32 | import java2typescript.jackson.module.util.ExpectedOutputChecker; 33 | import java2typescript.jackson.module.util.TestUtil; 34 | import java2typescript.jackson.module.writer.ExternalModuleFormatWriter; 35 | 36 | public class DefinitionGeneratorTest { 37 | 38 | @JsonTypeName("ChangedEnumName") 39 | static enum Enum { 40 | VAL1, VAL2, VAL3 41 | } 42 | 43 | class GenericClass { 44 | public T someField; 45 | } 46 | 47 | class TestClass { 48 | public String _String; 49 | public boolean _boolean; 50 | public Boolean _Boolean; 51 | public int _int; 52 | public float _float; 53 | public String[] stringArray; 54 | public Map map; 55 | public TestClass recursive; 56 | public TestClass[] recursiveArray; 57 | public ArrayList stringArrayList; 58 | public Collection booleanCollection; 59 | public Enum _enum; 60 | 61 | public String aMethod(boolean recParam, String param2) { 62 | return "toto"; 63 | } 64 | } 65 | 66 | public class StringClass extends GenericClass { 67 | 68 | } 69 | 70 | @Test 71 | public void internalModuleFormat() throws IOException { 72 | // Arrange 73 | Module module = createTestModule(); 74 | Writer out = new StringWriter(); 75 | 76 | // Act 77 | module.write(out); // for backwards compatibility the same as `new InternalModuleFormatWriter().write(module, out);` 78 | out.close(); 79 | System.out.println(out); 80 | 81 | // Assert 82 | ExpectedOutputChecker.checkOutputFromFile(out); 83 | } 84 | 85 | @Test 86 | public void externalModuleFormat() throws IOException { 87 | // Arrange 88 | Module module = createTestModule(); 89 | Writer out = new StringWriter(); 90 | 91 | // Act 92 | new ExternalModuleFormatWriter().write(module, out); 93 | out.close(); 94 | System.out.println(out); 95 | 96 | // Assert 97 | ExpectedOutputChecker.checkOutputFromFile(out); 98 | } 99 | 100 | class RecursiveTestClass { 101 | public RecursiveTestClass recursive; 102 | public RecursiveTestClass[] recursiveArray; 103 | 104 | public RecursiveTestClass returnThis() { 105 | return this; 106 | } 107 | } 108 | 109 | @Test 110 | public void classWithMethodReturningThis() throws IOException { 111 | // Arrange 112 | Module module = TestUtil.createTestModule(null, RecursiveTestClass.class); 113 | Writer out = new StringWriter(); 114 | 115 | // Act 116 | new ExternalModuleFormatWriter().write(module, out); 117 | out.close(); 118 | System.out.println(out); 119 | 120 | // Assert 121 | ExpectedOutputChecker.checkOutputFromFile(out); 122 | } 123 | 124 | @Test 125 | public void ambientModuleFormat() throws IOException { 126 | // Arrange 127 | Module module = createTestModule(); 128 | Writer out = new StringWriter(); 129 | 130 | // Act 131 | new AmbientModuleFormatWriter().write(module, out); 132 | out.close(); 133 | System.out.println(out); 134 | 135 | // Assert 136 | ExpectedOutputChecker.checkOutputFromFile(out); 137 | } 138 | 139 | private Module createTestModule() throws JsonMappingException { 140 | return TestUtil.createTestModule(null, TestClass.class, StringClass.class); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/ExcludedMethodsTest.java: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************************************* 3 | * Copyright 2013 Ats Uiboupin 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | ******************************************************************************/ 17 | package java2typescript.jackson.module; 18 | 19 | import java.beans.Transient; 20 | import java.io.IOException; 21 | import java.io.StringWriter; 22 | import java.io.Writer; 23 | 24 | import org.junit.Test; 25 | 26 | import java2typescript.jackson.module.grammar.Module; 27 | import java2typescript.jackson.module.util.ExpectedOutputChecker; 28 | import java2typescript.jackson.module.util.TestUtil; 29 | import java2typescript.jackson.module.writer.ExternalModuleFormatWriter; 30 | 31 | public class ExcludedMethodsTest { 32 | 33 | static class TestClass { 34 | public String field; 35 | 36 | // only public methods are included in output 37 | String nonPublicMethodsAreIgnored() { 38 | return null; 39 | } 40 | 41 | // Java Bean property getters are excluded even if field doesn't exist with exact name (field is generated instead) 42 | public String getBeanProperty() { 43 | return null; 44 | } 45 | 46 | // Java Bean property setters are excluded even if field doesn't exist with exact name (field is generated instead) 47 | public void setBeanProperty(String beanProperty) { 48 | } 49 | 50 | // methods annotated with @java.beans.Transient are excluded from output 51 | @Transient 52 | public String transientMethodsAreIgnoredByDefault() { 53 | return null; 54 | } 55 | 56 | // this method is added to the blacklist using conf.addIngoredMethod("blacklistedMethod") 57 | public String blacklistedMethod() { 58 | return null; 59 | } 60 | 61 | // this method is added to the blacklist using conf.addIngoredMethod("blacklistedStaticMethod") 62 | public static String blacklistedStaticMethod() { 63 | return null; 64 | } 65 | 66 | // --------------- END EXCLUDED METHODS 67 | 68 | public String instanceMetohd() { 69 | return null; 70 | } 71 | 72 | public static String staticMethod() { 73 | return null; 74 | } 75 | } 76 | 77 | @Test 78 | public void testExcludedMethods() throws IOException { 79 | // Arrange 80 | Configuration conf = new Configuration(); 81 | conf.addIngoredMethod("blacklistedMethod"); 82 | conf.addIngoredMethod("blacklistedStaticMethod"); 83 | Module module = TestUtil.createTestModule(conf, TestClass.class); 84 | Writer out = new StringWriter(); 85 | 86 | // Act 87 | new ExternalModuleFormatWriter().write(module, out); 88 | out.close(); 89 | System.out.println(out); 90 | 91 | // Assert 92 | ExpectedOutputChecker.checkOutputFromFile(out); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/StaticFieldExporterTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014 Florian Benz 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jackson.module; 17 | 18 | import static org.junit.Assert.assertFalse; 19 | import static org.junit.Assert.assertTrue; 20 | 21 | import java.io.IOException; 22 | import java.io.StringWriter; 23 | import java.io.Writer; 24 | import java.util.ArrayList; 25 | 26 | import java2typescript.jackson.module.grammar.Module; 27 | 28 | import org.junit.Test; 29 | 30 | import com.fasterxml.jackson.annotation.JsonTypeName; 31 | 32 | public class StaticFieldExporterTest { 33 | @JsonTypeName("ChangedEnumName") 34 | enum Enum { 35 | VAL1, VAL2, VAL3 36 | } 37 | 38 | static class TestClass { 39 | public static final boolean MY_CONSTANT_BOOLEAN = true; 40 | 41 | public static final String MY_CONSTANT_STRING = "Test"; 42 | 43 | public static final int MY_CONSTANT_INT = 10; 44 | 45 | public static final double MY_CONSTANT_DOUBLE = 42.12; 46 | 47 | public static final Enum MY_CONSTANT_ENUM = Enum.VAL1; 48 | 49 | public static final Enum[] MY_CONSTANT_ENUM_ARRAY = new Enum[] { Enum.VAL1 }; 50 | 51 | public static final Enum[] MY_CONSTANT_ENUM_ARRAY_2 = new Enum[] { Enum.VAL1, Enum.VAL2 }; 52 | 53 | public static final String[] MY_CONSTANT_ARRAY = new String[] { "Test" }; 54 | 55 | public static final int[] MY_CONSTANT_INT_ARRAY = new int[] { 10, 12 }; 56 | 57 | public static final double[] MY_CONSTANT_DOUBLE_ARRAY = new double[] { 42.12 }; 58 | 59 | public static final boolean[] MY_CONSTANT_BOOLEAN_ARRAY = new boolean[] { true, false, true }; 60 | 61 | public String doNotExportAsStatic; 62 | } 63 | 64 | @Test 65 | public void testTypeScriptDefinition() throws IOException, IllegalArgumentException { 66 | Writer out = new StringWriter(); 67 | 68 | ArrayList> classesToConvert = new ArrayList>(); 69 | classesToConvert.add(TestClass.class); 70 | 71 | Module module = new Module("mod"); 72 | new StaticFieldExporter(module, null).export(classesToConvert); 73 | 74 | module.write(out); 75 | 76 | out.close(); 77 | final String result = out.toString(); 78 | System.out.println(result); 79 | assertTrue(result.contains("export class TestClassStatic")); 80 | assertTrue(result.contains("export enum ChangedEnumName")); 81 | assertTrue(result.contains("static MY_CONSTANT_STRING: string = 'Test';")); 82 | assertTrue(result 83 | .contains("static MY_CONSTANT_ENUM_ARRAY_2: ChangedEnumName[] = [ ChangedEnumName.VAL1, ChangedEnumName.VAL2 ];")); 84 | assertFalse(result.contains("doNotExportAsStatic")); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/TypeRenamingWithAnnotationTest.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module; 2 | 3 | import java.io.IOException; 4 | import java.io.StringWriter; 5 | import java.io.Writer; 6 | 7 | import org.junit.Test; 8 | 9 | import com.fasterxml.jackson.annotation.JsonTypeName; 10 | 11 | import java2typescript.jackson.module.grammar.Module; 12 | import java2typescript.jackson.module.util.ExpectedOutputChecker; 13 | import java2typescript.jackson.module.util.TestUtil; 14 | import java2typescript.jackson.module.writer.ExternalModuleFormatWriter; 15 | 16 | public class TypeRenamingWithAnnotationTest { 17 | 18 | @JsonTypeName("EnumNameChangedWithAnnotation") 19 | static enum EnumToRename { 20 | VAL1, VAL2, VAL3 21 | } 22 | 23 | @JsonTypeName("ClassNameChangedWithAnnotation") 24 | static class ClassToRename { 25 | public EnumToRename enumToRename; 26 | } 27 | 28 | @Test 29 | public void nameChangedWithAnnotation() throws IOException { 30 | // Arrange 31 | Module module = TestUtil.createTestModule(null, EnumToRename.class, ClassToRename.class); 32 | Writer out = new StringWriter(); 33 | 34 | // Act 35 | new ExternalModuleFormatWriter().write(module, out); 36 | out.close(); 37 | System.out.println(out); 38 | 39 | // Assert 40 | ExpectedOutputChecker.checkOutputFromFile(out); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/TypeRenamingWithEnclosingClassTest.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module; 2 | 3 | import java.io.IOException; 4 | import java.io.StringWriter; 5 | import java.io.Writer; 6 | 7 | import org.junit.Test; 8 | 9 | import com.fasterxml.jackson.annotation.JsonTypeName; 10 | 11 | import java2typescript.jackson.module.conf.typename.WithEnclosingClassTSTypeNamingStrategy; 12 | import java2typescript.jackson.module.grammar.Module; 13 | import java2typescript.jackson.module.util.ExpectedOutputChecker; 14 | import java2typescript.jackson.module.util.TestUtil; 15 | import java2typescript.jackson.module.writer.ExternalModuleFormatWriter; 16 | 17 | public class TypeRenamingWithEnclosingClassTest { 18 | 19 | static class TestClass { 20 | public String fieldOfInnerClass; 21 | public java2typescript.jackson.module.TestClass other; 22 | public ClassToRename renamedWithAnnotation; 23 | } 24 | 25 | @JsonTypeName("ClassNameChangedWithAnnotation") 26 | static class ClassToRename { 27 | public String field; 28 | } 29 | 30 | @Test 31 | public void twoClassesWithSameName() throws IOException { 32 | // Arrange 33 | Configuration conf = new Configuration(); 34 | conf.setNamingStrategy(new WithEnclosingClassTSTypeNamingStrategy()); 35 | Module module = TestUtil.createTestModule(conf, TestClass.class); 36 | Writer out = new StringWriter(); 37 | 38 | // Act 39 | new ExternalModuleFormatWriter().write(module, out); 40 | out.close(); 41 | System.out.println(out); 42 | 43 | // Assert 44 | ExpectedOutputChecker.checkOutputFromFile(out); 45 | } 46 | 47 | } 48 | 49 | class TestClass { 50 | public String fieldOfPackageProtectedClass; 51 | } 52 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/WriterPreferencesTest.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module; 2 | 3 | import java.io.IOException; 4 | import java.io.StringWriter; 5 | import java.io.Writer; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import org.junit.Test; 11 | 12 | import java2typescript.jackson.module.grammar.Module; 13 | import java2typescript.jackson.module.util.ExpectedOutputChecker; 14 | import java2typescript.jackson.module.util.TestUtil; 15 | import java2typescript.jackson.module.writer.ExternalModuleFormatWriter; 16 | import java2typescript.jackson.module.writer.InternalModuleFormatWriter; 17 | 18 | /** 19 | * @author Ats Uiboupin 20 | */ 21 | public class WriterPreferencesTest { 22 | 23 | static class TestClass { 24 | public String someField; 25 | public Enum someEnum; 26 | } 27 | 28 | static enum Enum { 29 | VAL1, 30 | VAL2, 31 | name // lowercase "name" is special, can cause issues with JavaScript at runtime 32 | } 33 | 34 | static enum EnumOneValue { 35 | VAL1 36 | } 37 | 38 | static class Dummy { 39 | public String _String; 40 | } 41 | 42 | static class Constants { 43 | // constants in non-alfabetic order 44 | public static final String MY_CONSTANT_STRING = "stringValue"; 45 | public static final boolean MY_CONSTANT_BOOLEAN = true; 46 | } 47 | 48 | static class TestClassHasMapWithEnumKey { 49 | public Map enumKeyMap; 50 | } 51 | 52 | enum E{B,C,A} 53 | 54 | 55 | @Test 56 | public void enumToEnumPattern() throws IOException { 57 | // Arrange 58 | ExternalModuleFormatWriter mWriter = new ExternalModuleFormatWriter(); 59 | mWriter.preferences.useEnumPattern(); 60 | 61 | Module module = TestUtil.createTestModule(null, Enum.class); 62 | Writer out = new StringWriter(); 63 | 64 | // Act 65 | mWriter.write(module, out); 66 | out.close(); 67 | System.out.println(out); 68 | 69 | // Assert 70 | ExpectedOutputChecker.checkOutputFromFile(out); 71 | } 72 | 73 | @Test 74 | public void enumToStringLiteralType() throws IOException { 75 | // Arrange 76 | ExternalModuleFormatWriter mWriter = new ExternalModuleFormatWriter(); 77 | mWriter.preferences.useStringLiteralTypeForEnums(); 78 | 79 | Module module = TestUtil.createTestModule(null, Enum.class, EnumOneValue.class, TestClassHasMapWithEnumKey.class); 80 | Writer out = new StringWriter(); 81 | 82 | // Act 83 | mWriter.write(module, out); 84 | out.close(); 85 | System.out.println(out); 86 | 87 | // Assert 88 | ExpectedOutputChecker.checkOutputFromFile(out); 89 | } 90 | 91 | @Test 92 | public void enumToStringLiteralTypeWithConstants() throws IOException { 93 | // Arrange 94 | ExternalModuleFormatWriter mWriter = new ExternalModuleFormatWriter(); 95 | mWriter.preferences.useStringLiteralTypeForEnums(true); 96 | 97 | Module module = TestUtil.createTestModule(null, Enum.class, EnumOneValue.class); 98 | Writer out = new StringWriter(); 99 | 100 | // Act 101 | mWriter.write(module, out); 102 | out.close(); 103 | System.out.println(out); 104 | 105 | // Assert 106 | ExpectedOutputChecker.checkOutputFromFile(out); 107 | } 108 | 109 | @Test 110 | public void enumPatternBaseNotAddedWhenNotNeeded() throws IOException { 111 | // Arrange 112 | ExternalModuleFormatWriter mWriter = new ExternalModuleFormatWriter(); 113 | mWriter.preferences.useEnumPattern(); // should be ignored when no enums found 114 | 115 | Module module = TestUtil.createTestModule(null, Dummy.class); 116 | Writer out = new StringWriter(); 117 | 118 | // Act 119 | mWriter.write(module, out); 120 | out.close(); 121 | System.out.println(out); 122 | 123 | // Assert 124 | ExpectedOutputChecker.checkOutputFromFile(out); 125 | } 126 | 127 | @Test 128 | public void indentWithTabs() throws IOException { 129 | // Arrange 130 | InternalModuleFormatWriter writer = new InternalModuleFormatWriter(); 131 | writer.preferences.setIndentationStep("\t"); // custom indentation 132 | writer.preferences.useEnumPattern(); 133 | 134 | Configuration conf = null; // default conf 135 | Module module = TestUtil.createTestModule(conf, TestClass.class); 136 | List> toConvert = new ArrayList>(); 137 | toConvert.add(Constants.class); 138 | new StaticFieldExporter(module, conf).export(toConvert); 139 | Writer out = new StringWriter(); 140 | 141 | // Act 142 | writer.write(module, out); 143 | out.close(); 144 | System.out.println(out); 145 | 146 | // Assert 147 | ExpectedOutputChecker.checkOutputFromFile(out); 148 | } 149 | 150 | @Test 151 | public void sortOutputTypesAndVars() throws IOException { 152 | // Arrange 153 | ExternalModuleFormatWriter writer = new ExternalModuleFormatWriter(); 154 | Configuration conf = null; // default conf 155 | writer.preferences.sort(); 156 | 157 | @SuppressWarnings("unused") 158 | class F{ 159 | public String B; 160 | public String C; 161 | public String A; 162 | public void b() {}; 163 | public void c() {}; 164 | public void a() {}; 165 | } 166 | class Z{} 167 | class A{} 168 | class D{} 169 | 170 | Class[] classes = new Class[]{TestClass.class, D.class, Z.class, A.class, E.class, F.class}; 171 | 172 | Module module = TestUtil.createTestModule(conf, classes); 173 | 174 | List> toConvert = new ArrayList>(); 175 | toConvert.add(Constants.class); 176 | 177 | module.getVars().put("z", module.getNamedTypes().get(Z.class.getSimpleName())); 178 | module.getVars().put("a", module.getNamedTypes().get(A.class.getSimpleName())); 179 | 180 | new StaticFieldExporter(module, conf).export(toConvert); 181 | Writer out = new StringWriter(); 182 | 183 | // Act 184 | writer.write(module, out); 185 | out.close(); 186 | System.out.println(out); 187 | 188 | // Assert 189 | ExpectedOutputChecker.checkOutputFromFileEquals(out); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/util/ExpectedOutputChecker.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.util; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | import java.net.URL; 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | import org.junit.Assert; 10 | 11 | import com.google.common.base.Charsets; 12 | import com.google.common.collect.Lists; 13 | import com.google.common.io.Resources; 14 | 15 | public class ExpectedOutputChecker { 16 | 17 | public static void checkOutputFromFile(Writer out) { 18 | compareFileContent(out, getCaller()); 19 | } 20 | 21 | public static void checkOutputFromFileEquals(Writer out) { 22 | Assert.assertEquals(getExpectedOutput(getCaller()), out.toString()); 23 | } 24 | private static StackTraceElement getCaller() { 25 | return new Throwable().getStackTrace()[2]; 26 | } 27 | private static void compareFileContent(Writer out, StackTraceElement testMethodStackTraceElem) { 28 | // Can't rely on specific order of classes/fields/methods, so file content equality can't be used. 29 | // Using naive approach to check that actual output contains exactly the same lines as expected output 30 | Assert.assertEquals(getLinesAlphabetically(getExpectedOutput(testMethodStackTraceElem)), getLinesAlphabetically(out.toString())); 31 | } 32 | 33 | private static List getLinesAlphabetically(String s) { 34 | List lines = Lists.newArrayList(s.split("\\n")); 35 | Collections.sort(lines); 36 | return lines; 37 | } 38 | 39 | private static String getExpectedOutput(StackTraceElement testMethodStackTraceElem) { 40 | String testMethodName = testMethodStackTraceElem.getMethodName(); 41 | String className = testMethodStackTraceElem.getClassName(); 42 | String expectedOutputFromFile = getFileContent(className.replace('.', '/') + "." + testMethodName + ".d.ts"); 43 | expectedOutputFromFile = expectedOutputFromFile.replace("\r", ""); 44 | return expectedOutputFromFile; 45 | } 46 | 47 | private static String getFileContent(String resourceName) { 48 | URL url = Resources.getResource(resourceName); 49 | try { 50 | return Resources.toString(url, Charsets.UTF_8); 51 | } 52 | catch (IOException e) { 53 | throw new RuntimeException("failed to read content of " + url, e); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/java/java2typescript/jackson/module/util/TestUtil.java: -------------------------------------------------------------------------------- 1 | package java2typescript.jackson.module.util; 2 | 3 | import static com.google.common.collect.Lists.newArrayList; 4 | 5 | import com.fasterxml.jackson.databind.JsonMappingException; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | 8 | import java2typescript.jackson.module.Configuration; 9 | import java2typescript.jackson.module.DefinitionGenerator; 10 | import java2typescript.jackson.module.grammar.Module; 11 | 12 | public class TestUtil { 13 | 14 | public static Module createTestModule(Configuration conf, Class... classes) throws JsonMappingException { 15 | ObjectMapper mapper = new ObjectMapper(); 16 | DefinitionGenerator generator = new DefinitionGenerator(mapper); 17 | return generator.generateTypeScript("modName", newArrayList(classes), conf); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/ClassWithoutFieldsTest.classWithOnlyMethod.d.ts: -------------------------------------------------------------------------------- 1 | export interface ClassWithOnlyMethod { 2 | onlyMethod(): void; 3 | } 4 | 5 | 6 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/ClassWithoutFieldsTest.classWithoutFields.d.ts: -------------------------------------------------------------------------------- 1 | export interface ClassWithoutFields { 2 | } 3 | 4 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/ClassWithoutFieldsTest.referencesClassWithoutFields.d.ts: -------------------------------------------------------------------------------- 1 | export interface RererencesClassWithoutFields { 2 | classWithoutFields: ClassWithoutFields; 3 | javaLangObject: any; 4 | } 5 | 6 | export interface ClassWithoutFields { 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/CustomTypeDefinitionGeneratorTest.classWithCustomTypeFields.d.ts: -------------------------------------------------------------------------------- 1 | export interface TestClass { 2 | customDate: Date; 3 | customDateArray: Date[]; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/CustomTypeDefinitionGeneratorTest.declareTypeInsteadOfEmittingInterface.d.ts: -------------------------------------------------------------------------------- 1 | export interface TestClass { 2 | customDate: DateStringOrNumber; 3 | customDateArray: DateStringOrNumber[]; 4 | } 5 | 6 | export type DateStringOrNumber = string | number; 7 | 8 | export type NumericValue = number; 9 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/DefinitionGeneratorTest.ambientModuleFormat.d.ts: -------------------------------------------------------------------------------- 1 | declare module modName { 2 | 3 | export interface StringClass { 4 | someField: string; 5 | } 6 | 7 | export enum ChangedEnumName { 8 | VAL1, 9 | VAL2, 10 | VAL3, 11 | } 12 | 13 | export interface TestClass { 14 | _String: string; 15 | _boolean: boolean; 16 | _Boolean: boolean; 17 | _int: number; 18 | _float: number; 19 | stringArray: string[]; 20 | map: { [key: string ]: boolean;}; 21 | recursive: TestClass; 22 | recursiveArray: TestClass[]; 23 | stringArrayList: string[]; 24 | booleanCollection: boolean[]; 25 | _enum: ChangedEnumName; 26 | aMethod(param0: boolean, param1: string): string; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/DefinitionGeneratorTest.classWithMethodReturningThis.d.ts: -------------------------------------------------------------------------------- 1 | export interface RecursiveTestClass { 2 | recursive: RecursiveTestClass; 3 | recursiveArray: RecursiveTestClass[]; 4 | returnThis(): RecursiveTestClass; 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/DefinitionGeneratorTest.externalModuleFormat.d.ts: -------------------------------------------------------------------------------- 1 | export interface StringClass { 2 | someField: string; 3 | } 4 | 5 | export enum ChangedEnumName { 6 | VAL1, 7 | VAL2, 8 | VAL3, 9 | } 10 | 11 | export interface TestClass { 12 | _String: string; 13 | _boolean: boolean; 14 | _Boolean: boolean; 15 | _int: number; 16 | _float: number; 17 | stringArray: string[]; 18 | map: { [key: string ]: boolean;}; 19 | recursive: TestClass; 20 | recursiveArray: TestClass[]; 21 | stringArrayList: string[]; 22 | booleanCollection: boolean[]; 23 | _enum: ChangedEnumName; 24 | aMethod(param0: boolean, param1: string): string; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/DefinitionGeneratorTest.internalModuleFormat.d.ts: -------------------------------------------------------------------------------- 1 | export module modName { 2 | 3 | export interface StringClass { 4 | someField: string; 5 | } 6 | 7 | export enum ChangedEnumName { 8 | VAL1, 9 | VAL2, 10 | VAL3, 11 | } 12 | 13 | export interface TestClass { 14 | _String: string; 15 | _boolean: boolean; 16 | _Boolean: boolean; 17 | _int: number; 18 | _float: number; 19 | stringArray: string[]; 20 | map: { [key: string ]: boolean;}; 21 | recursive: TestClass; 22 | recursiveArray: TestClass[]; 23 | stringArrayList: string[]; 24 | booleanCollection: boolean[]; 25 | _enum: ChangedEnumName; 26 | aMethod(param0: boolean, param1: string): string; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/ExcludedMethodsTest.testExcludedMethods.d.ts: -------------------------------------------------------------------------------- 1 | export interface TestClass { 2 | field: string; 3 | beanProperty: string; 4 | instanceMetohd(): string; 5 | staticMethod(): string; 6 | } 7 | 8 | 9 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/TypeRenamingWithAnnotationTest.nameChangedWithAnnotation.d.ts: -------------------------------------------------------------------------------- 1 | export enum EnumNameChangedWithAnnotation { 2 | VAL1, 3 | VAL2, 4 | VAL3, 5 | } 6 | 7 | export interface ClassNameChangedWithAnnotation { 8 | enumToRename: EnumNameChangedWithAnnotation; 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/TypeRenamingWithEnclosingClassTest.twoClassesWithSameName.d.ts: -------------------------------------------------------------------------------- 1 | export interface TypeRenamingWithEnclosingClassTest$TestClass { 2 | fieldOfInnerClass: string; 3 | other: TestClass; 4 | renamedWithAnnotation: ClassNameChangedWithAnnotation; 5 | } 6 | 7 | export interface TestClass { 8 | fieldOfPackageProtectedClass: string; 9 | } 10 | 11 | export interface ClassNameChangedWithAnnotation { 12 | field: string; 13 | } -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/WriterPreferencesTest.enumPatternBaseNotAddedWhenNotNeeded.d.ts: -------------------------------------------------------------------------------- 1 | export interface Dummy { 2 | _String: string; 3 | } 4 | 5 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/WriterPreferencesTest.enumToEnumPattern.d.ts: -------------------------------------------------------------------------------- 1 | /** base class for implementing enums with Typesafe Enum Pattern (to be able to use enum names, instead of ordinal values, in a type-safe manner) */ 2 | export class EnumPatternBase { 3 | constructor(public name: string){} 4 | toString(){ return this.name; } 5 | } 6 | 7 | export class Enum extends EnumPatternBase { 8 | static VAL1 = new Enum('VAL1'); 9 | static VAL2 = new Enum('VAL2'); 10 | static name_ = new Enum('name'); 11 | constructor(name:string){super(name);} 12 | } 13 | 14 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/WriterPreferencesTest.enumToStringLiteralType.d.ts: -------------------------------------------------------------------------------- 1 | export type Enum = 2 | "VAL1" 3 | | "VAL2" 4 | | "name"; 5 | 6 | export interface TestClassHasMapWithEnumKey { 7 | enumKeyMap: { [key in Enum ] ? : string;}; 8 | } 9 | 10 | export type EnumOneValue = 11 | "VAL1"; 12 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/WriterPreferencesTest.enumToStringLiteralTypeWithConstants.d.ts: -------------------------------------------------------------------------------- 1 | export type Enum = 2 | "VAL1" 3 | | "VAL2" 4 | | "name"; 5 | 6 | export class EnumValues { 7 | static VAL1: Enum = "VAL1"; 8 | static VAL2: Enum = "VAL2"; 9 | static name_: Enum = "name"; 10 | } 11 | 12 | export type EnumOneValue = 13 | "VAL1"; 14 | 15 | export class EnumOneValueValues { 16 | static VAL1: EnumOneValue = "VAL1"; 17 | } 18 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/WriterPreferencesTest.indentWithTabs.d.ts: -------------------------------------------------------------------------------- 1 | export module modName { 2 | 3 | /** base class for implementing enums with Typesafe Enum Pattern (to be able to use enum names, instead of ordinal values, in a type-safe manner) */ 4 | export class EnumPatternBase { 5 | constructor(public name: string){} 6 | toString(){ return this.name; } 7 | } 8 | 9 | export class Enum extends EnumPatternBase { 10 | static VAL1 = new Enum('VAL1'); 11 | static VAL2 = new Enum('VAL2'); 12 | static name_ = new Enum('name'); 13 | constructor(name:string){super(name);} 14 | } 15 | 16 | export class ConstantsStatic { 17 | static MY_CONSTANT_BOOLEAN: boolean = true; 18 | static MY_CONSTANT_STRING: string = 'stringValue'; 19 | } 20 | 21 | export interface TestClass { 22 | someField: string; 23 | someEnum: Enum; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /java2typescript-jackson/src/test/resources/java2typescript/jackson/module/WriterPreferencesTest.sortOutputTypesAndVars.d.ts: -------------------------------------------------------------------------------- 1 | export interface A { 2 | } 3 | 4 | export class ConstantsStatic { 5 | static MY_CONSTANT_BOOLEAN: boolean = true; 6 | static MY_CONSTANT_STRING: string = 'stringValue'; 7 | } 8 | 9 | export interface D { 10 | } 11 | 12 | export enum E { 13 | A, 14 | B, 15 | C, 16 | } 17 | 18 | export enum Enum { 19 | VAL1, 20 | VAL2, 21 | name, 22 | } 23 | 24 | export interface F { 25 | A: string; 26 | B: string; 27 | C: string; 28 | a(): void; 29 | b(): void; 30 | c(): void; 31 | } 32 | 33 | export interface TestClass { 34 | someEnum: Enum; 35 | someField: string; 36 | } 37 | 38 | export interface Z { 39 | } 40 | 41 | export var a: A; 42 | export var z: Z; 43 | -------------------------------------------------------------------------------- /java2typescript-jaxrs/pom.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 4.0.0 10 | 11 | com.github.raphaeljolivet.java2typescript 12 | java2typescript 13 | v0.3.2-SNAPSHOT 14 | 15 | 16 | java2typescript-jaxrs 17 | java2typescript jaxrs 18 | 19 | A module to generate JSON descriptor and Typescript definition out of a REST Service, out of JAX-RS annotations 20 | 21 | 22 | javax.ws.rs 23 | jsr311-api 24 | 1.1.1 25 | 26 | 27 | com.esotericsoftware.kryo 28 | kryo 29 | 2.22 30 | 31 | 32 | com.google.guava 33 | guava 34 | 15.0 35 | 36 | 37 | ${project.groupId} 38 | java2typescript-jackson 39 | ${project.version} 40 | 41 | 42 | ${project.groupId} 43 | sample-web-app-server 44 | ${project.version} 45 | test 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /java2typescript-jaxrs/src/main/java/java2typescript/jaxrs/model/HttpMethod.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jaxrs.model; 17 | 18 | public enum HttpMethod { 19 | GET, // 20 | POST, // 21 | PUT, // 22 | DELETE 23 | } 24 | -------------------------------------------------------------------------------- /java2typescript-jaxrs/src/main/java/java2typescript/jaxrs/model/Param.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jaxrs.model; 17 | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; 19 | 20 | public class Param { 21 | private String name; 22 | private ParamType type; 23 | private boolean context = false; 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | public ParamType getType() { 34 | return type; 35 | } 36 | 37 | public void setType(ParamType type) { 38 | this.type = type; 39 | } 40 | 41 | /** If true, this param corresponds to a technical @Context param, and should be ignored in output generation */ 42 | @JsonIgnore 43 | public boolean isContext() { 44 | return context; 45 | } 46 | 47 | public void setContext(boolean context) { 48 | this.context = context; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /java2typescript-jaxrs/src/main/java/java2typescript/jaxrs/model/ParamType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jaxrs.model; 17 | 18 | public enum ParamType { 19 | QUERY, // 20 | PATH, // 21 | FORM, // 22 | BODY 23 | } 24 | -------------------------------------------------------------------------------- /java2typescript-jaxrs/src/main/java/java2typescript/jaxrs/model/RestMethod.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jaxrs.model; 17 | 18 | import java.util.List; 19 | 20 | import com.fasterxml.jackson.annotation.JsonIgnore; 21 | 22 | public class RestMethod { 23 | 24 | private String name; 25 | private String path; 26 | private List params; 27 | private HttpMethod httpMethod; 28 | 29 | public String getPath() { 30 | return path; 31 | } 32 | 33 | @JsonIgnore 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public void setName(String name) { 39 | this.name = name; 40 | } 41 | 42 | public void setPath(String path) { 43 | this.path = path; 44 | } 45 | 46 | public List getParams() { 47 | return params; 48 | } 49 | 50 | public void setParams(List params) { 51 | this.params = params; 52 | } 53 | 54 | public HttpMethod getHttpMethod() { 55 | return httpMethod; 56 | } 57 | 58 | public void setHttpMethod(HttpMethod httpMethod) { 59 | this.httpMethod = httpMethod; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /java2typescript-jaxrs/src/main/java/java2typescript/jaxrs/model/RestService.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jaxrs.model; 17 | 18 | import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT; 19 | 20 | import java.io.IOException; 21 | import java.io.Writer; 22 | import java.util.ArrayList; 23 | import java.util.Collection; 24 | import java.util.HashMap; 25 | import java.util.Iterator; 26 | import java.util.List; 27 | import java.util.Map; 28 | 29 | import com.esotericsoftware.kryo.Kryo; 30 | import com.fasterxml.jackson.core.JsonGenerationException; 31 | import com.fasterxml.jackson.databind.JsonMappingException; 32 | import com.fasterxml.jackson.databind.ObjectMapper; 33 | 34 | /** Root descrpition of a service */ 35 | public class RestService { 36 | 37 | private String name; 38 | private String path; 39 | private final Map methods = new HashMap(); 40 | 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | public String getPath() { 50 | return path; 51 | } 52 | 53 | public void setPath(String path) { 54 | this.path = path; 55 | } 56 | 57 | public Map getMethods() { 58 | return methods; 59 | } 60 | 61 | /** 62 | * Dump a JSON representation of the REST services 63 | */ 64 | static public void toJSON(Collection services, Writer writer) throws JsonGenerationException, 65 | JsonMappingException, IOException { 66 | 67 | ObjectMapper mapper = new ObjectMapper(); 68 | mapper.configure(INDENT_OUTPUT, true); 69 | 70 | List restServivcesWithoutParams = new ArrayList(); 71 | for (RestService restService : services) { 72 | restServivcesWithoutParams.add(copyWithoutContextParams(restService)); 73 | } 74 | 75 | mapper.writeValue(writer, restServivcesWithoutParams); 76 | } 77 | 78 | /** Re,ove @Context parameters from JSON definition before rendering */ 79 | static private RestService copyWithoutContextParams(RestService restService) { 80 | Kryo kryo = new Kryo(); 81 | RestService res = kryo.copy(restService); 82 | for (RestMethod method : res.getMethods().values()) { 83 | Iterator paramsIt = method.getParams().iterator(); 84 | while (paramsIt.hasNext()) { 85 | Param param = paramsIt.next(); 86 | if (param.isContext()) { 87 | paramsIt.remove(); 88 | } 89 | } 90 | } 91 | return res; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /java2typescript-jaxrs/src/main/resources/java2typescript/jaxrs/module-template.js: -------------------------------------------------------------------------------- 1 | // java2ts module 2 | j2ts = { 3 | 4 | // -- Adapters for REST calls 5 | adapters : { 6 | 7 | // >> To console 8 | console: function(httpMethod, path, getParams, postParams, body) { 9 | console.log([httpMethod, path, getParams, postParams, body]); 10 | }, 11 | 12 | // >> Jquery 13 | jQuery : function jQueryAdapter(httpMethod, url, getParams, postParams, body) { 14 | var processData = true; 15 | var data; 16 | if (getParams != null) { 17 | // in URL 18 | data = getParams; 19 | } else if (postParams != null) { 20 | // as form Params 21 | data = postParams; 22 | } else if (body != null) { 23 | // as JSON in body 24 | data = JSON.stringify(body); 25 | processData = false; 26 | } 27 | 28 | jQuery.ajax({ 29 | type : httpMethod, 30 | url : url, 31 | processData : processData, 32 | data : data 33 | }).done(function(data) { 34 | console.log(data); 35 | }) 36 | } // end of jQuery adapter 37 | } // end of adapters 38 | 39 | } // end of j2ts module definition 40 | 41 | j2ts.buildModule = function(serviceDescriptors) { 42 | 43 | var outModule = { 44 | 45 | rootUrl : null, 46 | 47 | // JQuery by default 48 | adapter : j2ts.adapters.jQuery 49 | 50 | }; 51 | 52 | function methodGenerator(methodDesc) { 53 | 54 | return function() { 55 | 56 | if (outModule.rootUrl == null) { 57 | throw new Error("rootUrl is null, set it before calling rest methods"); 58 | } 59 | 60 | var url = outModule.rootUrl + desc.path + methodDesc.path 61 | 62 | // Init params to be passed to adapter function 63 | var getParams = null; 64 | var postParams = null; 65 | var body = null; 66 | 67 | // Loop on params 68 | for (var i=0; i< methodDesc.params.length; i++) { 69 | var paramValue = arguments[i]; 70 | var paramDesc = methodDesc.params[i]; 71 | 72 | switch(paramDesc.type) { 73 | case "FORM" : 74 | if (postParams == null) postParams = {}; 75 | postParams[paramDesc.name] = paramValue; 76 | break; 77 | case "QUERY" : 78 | if (getParams == null) getParams = {}; 79 | getParams[paramDesc.name] = paramValue; 80 | break; 81 | case "PATH" : 82 | url = url.replace("{" + paramDesc.name + "}", paramValue) 83 | break; 84 | case "BODY" : 85 | body = paramValue; 86 | } 87 | } 88 | 89 | // Actual call to the adapter 90 | outModule.adapter(methodDesc.httpMethod, url, getParams, postParams, body); 91 | } 92 | } 93 | 94 | // Loop on services 95 | for (var i = 0; i < serviceDescriptors.length; i++) { 96 | 97 | // Add service to module 98 | serviceDescriptor = serviceDescriptors[i]; 99 | outService = {} 100 | outModule[serviceDescriptor.name] = outService; 101 | 102 | // Add methods to service 103 | for (var methodName in serviceDescriptor.methods) { 104 | var methodDesc = desc.methods[methodName]; 105 | outService[methodName] = methodGenerator(methodDesc); 106 | } 107 | } 108 | 109 | 110 | 111 | return outModule; 112 | } 113 | 114 | %MODULE_NAME% = j2ts.buildModule(%JSON%); 115 | 116 | 117 | -------------------------------------------------------------------------------- /java2typescript-jaxrs/src/test/java/java2typescript/jaxrs/DescriptorGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Raphael Jolivet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package java2typescript.jaxrs; 17 | 18 | import java.io.IOException; 19 | import java.io.OutputStreamWriter; 20 | import java.io.Writer; 21 | import java.util.Collections; 22 | import java2typescript.jackson.module.grammar.Module; 23 | 24 | import javax.ws.rs.FormParam; 25 | import javax.ws.rs.GET; 26 | import javax.ws.rs.POST; 27 | import javax.ws.rs.Path; 28 | import javax.ws.rs.PathParam; 29 | import javax.ws.rs.QueryParam; 30 | 31 | import org.junit.Before; 32 | import org.junit.Test; 33 | 34 | import com.example.rs.PeopleRestService; 35 | import com.fasterxml.jackson.core.JsonGenerationException; 36 | import com.fasterxml.jackson.databind.JsonMappingException; 37 | import com.fasterxml.jackson.databind.ObjectMapper; 38 | import com.fasterxml.jackson.databind.module.SimpleModule; 39 | 40 | public class DescriptorGeneratorTest { 41 | 42 | private Writer out; 43 | 44 | static class MyObject { 45 | public String field; 46 | } 47 | 48 | @Path("/") 49 | static private interface ExampleService { 50 | 51 | @Path("/{id}") 52 | @POST 53 | public String aPostMethod(// 54 | @QueryParam("q1") String queryParam, // 55 | @PathParam("id") String id, // 56 | @FormParam("formParam") Integer formParam, // 57 | String postPayload); 58 | 59 | @Path("/{id}") 60 | @GET 61 | public void aGetMethod(// 62 | @QueryParam("q1") String queryParam, // 63 | @PathParam("id") String id, // 64 | @FormParam("formParam") Integer formParam, // 65 | MyObject postPayload); 66 | 67 | } 68 | 69 | @Before 70 | public void setUp() { 71 | out = new OutputStreamWriter(System.out); 72 | } 73 | 74 | @Test 75 | public void testJSGenerate() throws JsonGenerationException, JsonMappingException, IOException { 76 | ServiceDescriptorGenerator descGen = new ServiceDescriptorGenerator( 77 | Collections.singletonList(PeopleRestService.class)); 78 | descGen.generateJavascript("moduleName", out); 79 | } 80 | 81 | @Test 82 | public void testTypescriptGenerate() throws JsonGenerationException, JsonMappingException, IOException { 83 | 84 | ServiceDescriptorGenerator descGen = new ServiceDescriptorGenerator( 85 | Collections.singletonList(PeopleRestService.class)); 86 | 87 | ObjectMapper mapper = new ObjectMapper(); 88 | SimpleModule module = new SimpleModule("custom-mapping"); 89 | 90 | mapper.registerModule(module); 91 | 92 | Module tsModule = descGen.generateTypeScript("modName"); 93 | tsModule.write(out); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /java2typescript-maven-plugin/README.md: -------------------------------------------------------------------------------- 1 | # Purpose 2 | 3 | This **maven** plugin is part of the [java2typescript](..) project. 4 | It generates a typescript definition of REST services and corresponding DTO model out of [JAX-RS](https://jax-rs-spec.java.net/) annotated Java services. 5 | 6 | # Goals 7 | 8 | There is a single goal **generate** that generates both `.ts` and `.js` files 9 | 10 | ``` 11 | mvn java2typescript:generate 12 | ``` 13 | 14 | # Parameters 15 | 16 | Here are the parameters handled by the plugin 17 | 18 | | Name | Expression | Default value | Meaning | 19 | |----------------|-------------------|----------------------------|--------------------------| 20 | | serviceClass | j2ts.serviceClass | - | Class of REST service | 21 | | moduleName | j2ts.moduleName | - | Name of output module | 22 | | tsOutFolder | j2ts.tsOutFolder | ${project.build.directory} | Output folder for ts file| 23 | | jsOutFolder | j2ts.jsOutFolder | ${project.build.directory} | Output folder for js file| 24 | 25 | By default the two files will be generated as : 26 | * `/.d.ts` 27 | * `/.js` 28 | 29 | # Setup 30 | 31 | To use this plugin, you first need to declare a custom repository : 32 | 33 | ```xml 34 | 35 | 36 | jitpack.io2 37 | jitpack.io Plugin Repository 38 | https://jitpack.io 39 | default 40 | 41 | true 42 | 43 | 44 | always 45 | 46 | 47 | 48 | ``` 49 | 50 | and add the plugin: 51 | ```xml 52 | 53 | 54 | 55 | com.github.raphaeljolivet.java2typescript 56 | java2typescript-maven-plugin 57 | FIXME-change-the-version 58 | 59 | 60 | com.example.rs.PeopleRestService 61 | People 62 | 63 | 64 | 65 | 66 | ``` 67 | 68 | > Note, that You should change the configuration properties (see above) and plugin version (take a look at [installation instruction](../../../#installation)s from parent project) 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /java2typescript-maven-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.github.raphaeljolivet.java2typescript 6 | java2typescript 7 | v0.3.2-SNAPSHOT 8 | 9 | 10 | java2typescript-maven-plugin 11 | maven-plugin 12 | java2typescript maven plugin 13 | http://maven.apache.org 14 | 15 | 16 | 2.2.1 17 | 18 | 19 | 20 | 21 | 22 | org.codehaus.plexus 23 | plexus-maven-plugin 24 | 1.3.8 25 | 26 | 27 | 28 | descriptor 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | org.eclipse.m2e 40 | lifecycle-mapping 41 | 1.0.0 42 | 43 | 44 | 45 | 46 | 47 | org.codehaus.plexus 48 | plexus-maven-plugin 49 | 50 | 1.3.8 51 | 52 | descriptor 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.apache.maven 71 | maven-artifact 72 | ${maven.version} 73 | 74 | 75 | org.apache.maven 76 | maven-plugin-api 77 | ${maven.version} 78 | 79 | 80 | org.apache.maven 81 | maven-project 82 | ${maven.version} 83 | 84 | 85 | org.apache.maven 86 | maven-model 87 | ${maven.version} 88 | 89 | 90 | 91 | org.apache.maven 92 | maven-core 93 | 2.0.9 94 | 95 | 96 | com.google.guava 97 | guava 98 | 15.0 99 | 100 | 101 | 102 | junit 103 | junit 104 | 3.8.1 105 | test 106 | 107 | 108 | org.codehaus.plexus 109 | plexus-maven-plugin 110 | 1.3.8 111 | 112 | 113 | ${project.groupId} 114 | java2typescript-jaxrs 115 | ${project.version} 116 | 117 | 118 | 119 | 120 | 121 | 122 | org.apache.maven.plugins 123 | maven-plugin-plugin 124 | 3.2 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /java2typescript-maven-plugin/src/main/java/org/java2typescript/maven/plugin/IncludeProjectDependenciesComponentConfigurator.java: -------------------------------------------------------------------------------- 1 | package org.java2typescript.maven.plugin; 2 | 3 | import java.io.File; 4 | import java.net.MalformedURLException; 5 | import java.net.URL; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.codehaus.classworlds.ClassRealm; 10 | import org.codehaus.plexus.component.configurator.AbstractComponentConfigurator; 11 | import org.codehaus.plexus.component.configurator.ComponentConfigurationException; 12 | import org.codehaus.plexus.component.configurator.ConfigurationListener; 13 | import org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter; 14 | import org.codehaus.plexus.component.configurator.converters.special.ClassRealmConverter; 15 | import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; 16 | import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; 17 | import org.codehaus.plexus.configuration.PlexusConfiguration; 18 | 19 | /** 20 | * A custom ComponentConfigurator which adds the project's runtime classpath 21 | * elements to the 22 | * 23 | * @author Brian Jackson 24 | * @since Aug 1, 2008 3:04:17 PM 25 | * 26 | * @plexus.component 27 | * role="org.codehaus.plexus.component.configurator.ComponentConfigurator" 28 | * role-hint="include-project-dependencies" 29 | * @plexus.requirement role= 30 | * "org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup" 31 | * role-hint="default" 32 | */ 33 | public class IncludeProjectDependenciesComponentConfigurator extends AbstractComponentConfigurator { 34 | 35 | @Override 36 | public void configureComponent(Object component, PlexusConfiguration configuration, 37 | ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm, ConfigurationListener listener) 38 | throws ComponentConfigurationException { 39 | 40 | addProjectDependenciesToClassRealm(expressionEvaluator, containerRealm); 41 | 42 | converterLookup.registerConverter(new ClassRealmConverter(containerRealm)); 43 | 44 | ObjectWithFieldsConverter converter = new ObjectWithFieldsConverter(); 45 | 46 | converter.processConfiguration(converterLookup, component, containerRealm.getClassLoader(), configuration, 47 | expressionEvaluator, listener); 48 | } 49 | 50 | private void addProjectDependenciesToClassRealm(ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm) 51 | throws ComponentConfigurationException { 52 | List runtimeClasspathElements; 53 | try { 54 | // noinspection unchecked 55 | runtimeClasspathElements = (List) expressionEvaluator 56 | .evaluate("${project.runtimeClasspathElements}"); 57 | } catch (ExpressionEvaluationException e) { 58 | throw new ComponentConfigurationException( 59 | "There was a problem evaluating: ${project.runtimeClasspathElements}", e); 60 | } 61 | 62 | // Add the project dependencies to the ClassRealm 63 | final URL[] urls = buildURLs(runtimeClasspathElements); 64 | for (URL url : urls) { 65 | containerRealm.addConstituent(url); 66 | } 67 | } 68 | 69 | private URL[] buildURLs(List runtimeClasspathElements) throws ComponentConfigurationException { 70 | // Add the projects classes and dependencies 71 | List urls = new ArrayList(runtimeClasspathElements.size()); 72 | for (String element : runtimeClasspathElements) { 73 | try { 74 | final URL url = new File(element).toURI().toURL(); 75 | urls.add(url); 76 | } catch (MalformedURLException e) { 77 | throw new ComponentConfigurationException("Unable to access project dependency: " + element, e); 78 | } 79 | } 80 | 81 | // Add the plugin's dependencies (so Trove stuff works if Trove isn't on 82 | return urls.toArray(new URL[urls.size()]); 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /java2typescript-maven-plugin/src/main/java/org/java2typescript/maven/plugin/MainMojo.java: -------------------------------------------------------------------------------- 1 | package org.java2typescript.maven.plugin; 2 | 3 | /* 4 | * Copyright 2001-2005 The Apache Software Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.File; 20 | import java.io.FileOutputStream; 21 | import java.io.IOException; 22 | import java.io.OutputStreamWriter; 23 | import java.io.Writer; 24 | import java2typescript.jackson.module.grammar.Module; 25 | import java2typescript.jaxrs.ServiceDescriptorGenerator; 26 | 27 | import org.apache.maven.plugin.AbstractMojo; 28 | import org.apache.maven.plugin.MojoExecutionException; 29 | 30 | import com.google.common.collect.Lists; 31 | 32 | /** 33 | * Generate typescript file out of RESt service definition 34 | * 35 | * @goal generate 36 | * @phase process-classes 37 | * @configurator include-project-dependencies 38 | * @requiresDependencyResolution compile+runtime 39 | */ 40 | public class MainMojo extends AbstractMojo { 41 | 42 | /** 43 | * Full class name of the REST service 44 | * @required 45 | * @parameter 46 | * alias="serviceClass" 47 | * expression="${j2ts.serviceClass}" 48 | */ 49 | private String restServiceClassName; 50 | 51 | /** 52 | * Name of output module (ts,js) 53 | * @required 54 | * @parameter 55 | * alias="moduleName" 56 | * expression="${j2ts.moduleName}" 57 | */ 58 | private String moduleName; 59 | 60 | /** 61 | * Path to output typescript folder 62 | * The name will be .d.ts 63 | * @required 64 | * @parameter 65 | * alias="tsOutFolder" 66 | * expression="${j2ts.tsOutFolder}" 67 | * default-value = "${project.build.directory}" 68 | */ 69 | private File tsOutFolder; 70 | 71 | /** 72 | * Path to output Js file 73 | * The name will be .js 74 | * 75 | * @required 76 | * @parameter 77 | * alias="jsOutFolder" 78 | * expression="${j2ts.jsOutFolder}" 79 | * default-value = "${project.build.directory}" 80 | */ 81 | private File jsOutFolder; 82 | 83 | @Override 84 | public void execute() throws MojoExecutionException { 85 | 86 | try { 87 | 88 | // Descriptor for service 89 | Class serviceClass = Class.forName(restServiceClassName); 90 | ServiceDescriptorGenerator descGen = new ServiceDescriptorGenerator(Lists.newArrayList(serviceClass)); 91 | 92 | // To Typescript 93 | { 94 | Writer writer = createFileAndGetWriter(tsOutFolder, moduleName + ".d.ts"); 95 | Module tsModule = descGen.generateTypeScript(moduleName); 96 | tsModule.write(writer); 97 | writer.close(); 98 | } 99 | 100 | // To JS 101 | { 102 | Writer outFileWriter = createFileAndGetWriter(jsOutFolder, moduleName + ".js"); 103 | descGen.generateJavascript(moduleName, outFileWriter); 104 | outFileWriter.close(); 105 | } 106 | 107 | } catch (Exception e) { 108 | throw new MojoExecutionException(e.getMessage(), e); 109 | } 110 | } 111 | 112 | private Writer createFileAndGetWriter(File folder, String fileName) throws IOException { 113 | File file = new File(folder, fileName); 114 | getLog().info("Create file : " + file.getCanonicalPath()); 115 | file.createNewFile(); 116 | FileOutputStream stream = new FileOutputStream(file); 117 | OutputStreamWriter writer = new OutputStreamWriter(stream); 118 | return writer; 119 | }; 120 | } 121 | -------------------------------------------------------------------------------- /java2typescript-maven-plugin/src/main/resources/org/java2typescript/maven/plugin/module-template.js: -------------------------------------------------------------------------------- 1 | // java2ts module 2 | j2ts = { 3 | 4 | // -- Adapters for REST calls 5 | adapters : { 6 | 7 | // >> To console 8 | console: function(httpMethod, path, getParams, postParams, body) { 9 | console.log([httpMethod, path, getParams, postParams, body]); 10 | }, 11 | 12 | // >> Jquery 13 | jQuery : function jQueryAdapter(httpMethod, url, getParams, postParams, body) { 14 | var processData = true; 15 | var data; 16 | if (getParams != null) { 17 | // in URL 18 | data = getParams; 19 | } else if (postParams != null) { 20 | // as form Params 21 | data = postParams; 22 | } else if (body != null) { 23 | // as JSON in body 24 | data = JSON.stringify(body); 25 | processData = false; 26 | } 27 | 28 | jQuery.ajax({ 29 | type : httpMethod, 30 | url : url, 31 | processData : processData, 32 | data : data 33 | }).done(function(data) { 34 | console.log(data); 35 | }) 36 | } // end of jQuery adapter 37 | } // end of adapters 38 | 39 | } // end of j2ts module definition 40 | 41 | j2ts.buildModule = function(serviceDescriptors) { 42 | 43 | var outModule = { 44 | 45 | rootUrl : null, 46 | 47 | // JQuery by default 48 | adapter : j2ts.adapters.jQuery 49 | 50 | }; 51 | 52 | function methodGenerator(methodDesc) { 53 | 54 | return function() { 55 | 56 | if (outModule.rootUrl == null) { 57 | throw new Error("rootUrl is null, set it before calling rest methods"); 58 | } 59 | 60 | var url = outModule.rootUrl + desc.path + methodDesc.path 61 | 62 | // Init params to be passed to adapter function 63 | var getParams = null; 64 | var postParams = null; 65 | var body = null; 66 | 67 | // Loop on params 68 | for (var i=0; i< methodDesc.params.length; i++) { 69 | var paramValue = arguments[i]; 70 | var paramDesc = methodDesc.params[i]; 71 | 72 | switch(paramDesc.type) { 73 | case "FORM" : 74 | if (postParams == null) postParams = {}; 75 | postParams[paramDesc.name] = paramValue; 76 | break; 77 | case "QUERY" : 78 | if (getParams == null) getParams = {}; 79 | getParams[paramDesc.name] = paramValue; 80 | break; 81 | case "PATH" : 82 | url = url.replace("{" + paramDesc.name + "}", paramValue) 83 | break; 84 | case "BODY" : 85 | body = paramValue; 86 | } 87 | } 88 | 89 | // Actual call to the adapter 90 | outModule.adapter(methodDesc.httpMethod, url, getParams, postParams, body); 91 | } 92 | } 93 | 94 | // Loop on services 95 | for (var i = 0; i < serviceDescriptors.length; i++) { 96 | 97 | // Add service to module 98 | serviceDescriptor = serviceDescriptors[i]; 99 | outService = {} 100 | outModule[serviceDescriptor.name] = outService; 101 | 102 | // Add methods to service 103 | for (var methodName in serviceDescriptor.methods) { 104 | var methodDesc = desc.methods[methodName]; 105 | outService[methodName] = methodGenerator(methodDesc); 106 | } 107 | } 108 | 109 | 110 | 111 | return outModule; 112 | } 113 | 114 | %MODULE_NAME% = j2ts.buildModule(%JSON%); 115 | 116 | 117 | -------------------------------------------------------------------------------- /java2typescript-maven-plugin/src/site/apt/index.apt.vm: -------------------------------------------------------------------------------- 1 | ----- 2 | Introduction 3 | ----- 4 | 5 | ${project.name} 6 | 7 | 8 | -------------------------------------------------------------------------------- /java2typescript-maven-plugin/src/site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 28 | 29 | org.apache.maven.skins 30 | maven-fluido-skin 31 | 1.3.0 32 | 33 | 34 |

35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.github.raphaeljolivet.java2typescript 5 | java2typescript 6 | v0.3.2-SNAPSHOT 7 | pom 8 | java2typescript 9 | 10 | 11 | 1.6 12 | 1.6 13 | github 14 | 15 | 16 | 17 | java2typescript-jackson 18 | java2typescript-jaxrs 19 | java2typescript-maven-plugin 20 | sample-web-app-server 21 | sample-web-app-client 22 | 23 | 24 | 25 | 26 | junit 27 | junit 28 | 4.8.2 29 | test 30 | 31 | 32 | 33 | 34 | 35 | internal.repo 36 | local-target 37 | file://${project.build.directory}/mvn-repo 38 | 39 | 40 | internal.snaphshot.repo 41 | local-target 42 | file://${project.build.directory}/mvn-repo-snapshots 43 | 44 | 45 | 46 | 47 | scm:git:git@github.com:raphaeljolivet/jackson-module-typescript.git 48 | scm:git:git@github.com:raphaeljolivet/jackson-module-typescript.git 49 | scm:git:git@github.com:raphaeljolivet/jackson-module-typescript.git 50 | 51 | 52 | 53 | 54 | 55 | org.apache.maven.plugins 56 | maven-javadoc-plugin 57 | 2.9.1 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | com.github.github 66 | site-maven-plugin 67 | 0.8 68 | 69 | Maven artifacts for ${project.version} 70 | true 71 | ${project.build.directory}/mvn-repo 72 | refs/heads/mvn-repo 73 | **/* 74 | java2typescript 75 | raphaeljolivet 76 | true 77 | 78 | 79 | 80 | 81 | 82 | site 83 | 84 | deploy 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /sample-web-app-client/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.github.raphaeljolivet.java2typescript 7 | java2typescript 8 | v0.3.2-SNAPSHOT 9 | 10 | 11 | sample-web-app-client 12 | jar 13 | 14 | 15 | UTF-8 16 | 2.7.2 17 | 3.2.0.RELEASE 18 | 8.1.8.v20121106 19 | 20 | 21 | 22 | 23 | 24 | com.github.raphaeljolivet.java2typescript 25 | java2typescript-maven-plugin 26 | v0.3.2-SNAPSHOT 27 | 28 | com.example.rs.PeopleRestService 29 | People 30 | ${project.build.directory} 31 | ${project.build.directory} 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | maven2-repository.dev.java.net 41 | Java.net Repository for Maven 42 | http://download.java.net/maven/2/ 43 | default 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /sample-web-app-server/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /.project 3 | /.classpath 4 | /.settings 5 | -------------------------------------------------------------------------------- /sample-web-app-server/README.md: -------------------------------------------------------------------------------- 1 | spring-one-jar 2 | ============== 3 | 4 | - curl http://localhost:8080/rest/api/people -X PUT -d "email=a@b.com" 5 | - curl http://localhost:8080/rest/api/people?page=2 6 | -------------------------------------------------------------------------------- /sample-web-app-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.github.raphaeljolivet.java2typescript 6 | java2typescript 7 | v0.3.2-SNAPSHOT 8 | 9 | 10 | sample-web-app-server 11 | jar 12 | 13 | 14 | UTF-8 15 | 2.7.2 16 | 3.2.0.RELEASE 17 | 8.1.8.v20121106 18 | 1.6 19 | 20 | 21 | 22 | 23 | org.apache.cxf 24 | cxf-rt-frontend-jaxrs 25 | ${org.apache.cxf.version} 26 | 27 | 28 | 29 | javax.inject 30 | javax.inject 31 | 1 32 | 33 | 34 | 35 | org.codehaus.jackson 36 | jackson-jaxrs 37 | 1.9.11 38 | 39 | 40 | 41 | org.codehaus.jackson 42 | jackson-mapper-asl 43 | 1.9.11 44 | 45 | 46 | 47 | cglib 48 | cglib-nodep 49 | 2.2 50 | 51 | 52 | 53 | org.springframework 54 | spring-core 55 | ${org.springframework.version} 56 | 57 | 58 | 59 | org.springframework 60 | spring-context 61 | ${org.springframework.version} 62 | 63 | 64 | 65 | org.springframework 66 | spring-web 67 | ${org.springframework.version} 68 | 69 | 70 | 71 | org.eclipse.jetty 72 | jetty-server 73 | ${org.eclipse.jetty.version} 74 | 75 | 76 | 77 | org.eclipse.jetty 78 | jetty-util 79 | ${org.eclipse.jetty.version} 80 | 81 | 82 | 83 | org.eclipse.jetty 84 | jetty-webapp 85 | ${org.eclipse.jetty.version} 86 | 87 | 88 | 89 | 90 | 91 | 92 | org.apache.maven.plugins 93 | maven-compiler-plugin 94 | 3.0 95 | 96 | ${compiler.version} 97 | ${compiler.version} 98 | 99 | 100 | 101 | 102 | org.apache.maven.plugins 103 | maven-jar-plugin 104 | 2.5 105 | 106 | 107 | 108 | com.example.Starter 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | maven2-repository.dev.java.net 119 | Java.net Repository for Maven 120 | http://download.java.net/maven/2/ 121 | default 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/java/com/example/Starter.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import java.io.IOException; 4 | import java.net.URISyntaxException; 5 | 6 | import org.apache.cxf.transport.servlet.CXFServlet; 7 | import org.eclipse.jetty.server.Server; 8 | import org.eclipse.jetty.server.handler.HandlerCollection; 9 | import org.eclipse.jetty.server.handler.ResourceHandler; 10 | import org.eclipse.jetty.servlet.ServletContextHandler; 11 | import org.eclipse.jetty.servlet.ServletHolder; 12 | import org.springframework.web.context.ContextLoaderListener; 13 | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; 14 | 15 | import com.example.config.AppConfig; 16 | 17 | public class Starter { 18 | public static void main(final String[] args) throws Exception { 19 | 20 | Server server = new Server(8080); 21 | HandlerCollection handlerCollection = new HandlerCollection(); 22 | server.setHandler(handlerCollection); 23 | 24 | addSpringContext(handlerCollection); 25 | 26 | // Default one, resourceHandler takes everything 27 | addStaticContext(handlerCollection); 28 | 29 | server.start(); 30 | server.join(); 31 | } 32 | 33 | static private void addSpringContext(HandlerCollection collection) { 34 | final ServletHolder servletHolder = new ServletHolder(new CXFServlet()); 35 | final ServletContextHandler context = new ServletContextHandler(); 36 | context.setContextPath("/"); 37 | 38 | context.addServlet(servletHolder, "/rest/*"); 39 | context.addEventListener(new ContextLoaderListener()); 40 | 41 | context.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName()); 42 | context.setInitParameter("contextConfigLocation", AppConfig.class.getName()); 43 | 44 | collection.addHandler(context); 45 | } 46 | 47 | static private void addStaticContext(HandlerCollection collection) { 48 | ResourceHandler resHandler = new ResourceHandler(); 49 | resHandler.setWelcomeFiles(new String[] { "index.html" }); 50 | try { 51 | resHandler.setBaseResource(new org.eclipse.jetty.util.resource.FileResource(Starter.class 52 | .getResource("/WEB-INF/"))); 53 | } 54 | catch (Exception e) { 55 | throw new RuntimeException(e); 56 | } 57 | collection.addHandler(resHandler); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/java/com/example/config/AppConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.config; 2 | 3 | import java.util.Arrays; 4 | 5 | import javax.ws.rs.ext.RuntimeDelegate; 6 | 7 | import org.apache.cxf.bus.spring.SpringBus; 8 | import org.apache.cxf.endpoint.Server; 9 | import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; 10 | import org.codehaus.jackson.jaxrs.JacksonJsonProvider; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.context.annotation.DependsOn; 14 | 15 | import com.example.rs.JaxRsApiApplication; 16 | import com.example.rs.PeopleRestService; 17 | import com.example.services.PeopleService; 18 | 19 | @Configuration 20 | public class AppConfig { 21 | @Bean( destroyMethod = "shutdown" ) 22 | public SpringBus cxf() { 23 | return new SpringBus(); 24 | } 25 | 26 | @Bean @DependsOn( "cxf" ) 27 | public Server jaxRsServer() { 28 | JAXRSServerFactoryBean factory = RuntimeDelegate.getInstance().createEndpoint( jaxRsApiApplication(), JAXRSServerFactoryBean.class ); 29 | factory.setServiceBeans( Arrays.< Object >asList( peopleRestService() ) ); 30 | factory.setAddress( "/" + factory.getAddress() ); 31 | factory.setProviders( Arrays.< Object >asList( jsonProvider() ) ); 32 | return factory.create(); 33 | } 34 | 35 | @Bean 36 | public JaxRsApiApplication jaxRsApiApplication() { 37 | return new JaxRsApiApplication(); 38 | } 39 | 40 | @Bean 41 | public PeopleRestService peopleRestService() { 42 | return new PeopleRestService(); 43 | } 44 | 45 | @Bean 46 | public PeopleService peopleService() { 47 | return new PeopleService(); 48 | } 49 | 50 | @Bean 51 | public JacksonJsonProvider jsonProvider() { 52 | return new JacksonJsonProvider(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/java/com/example/exceptions/PersonAlreadyExistsException.java: -------------------------------------------------------------------------------- 1 | package com.example.exceptions; 2 | 3 | import javax.ws.rs.WebApplicationException; 4 | import javax.ws.rs.core.Response; 5 | import javax.ws.rs.core.Response.Status; 6 | 7 | public class PersonAlreadyExistsException extends WebApplicationException { 8 | private static final long serialVersionUID = 6817489620338221395L; 9 | 10 | public PersonAlreadyExistsException( final String email ) { 11 | super( 12 | Response 13 | .status( Status.CONFLICT ) 14 | .entity( "Person already exists: " + email ) 15 | .build() 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/java/com/example/exceptions/PersonNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.exceptions; 2 | 3 | import javax.ws.rs.WebApplicationException; 4 | import javax.ws.rs.core.Response; 5 | import javax.ws.rs.core.Response.Status; 6 | 7 | public class PersonNotFoundException extends WebApplicationException { 8 | private static final long serialVersionUID = -2894269137259898072L; 9 | 10 | public PersonNotFoundException( final String email ) { 11 | super( 12 | Response 13 | .status( Status.NOT_FOUND ) 14 | .entity( "Person not found: " + email ) 15 | .build() 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/java/com/example/model/Person.java: -------------------------------------------------------------------------------- 1 | package com.example.model; 2 | 3 | public class Person { 4 | private String email; 5 | private String firstName; 6 | private String lastName; 7 | 8 | public Person() { 9 | } 10 | 11 | public Person( final String email ) { 12 | this.email = email; 13 | } 14 | 15 | public Person( final String firstName, final String lastName ) { 16 | this.firstName = firstName; 17 | this.lastName = lastName; 18 | } 19 | 20 | public String getEmail() { 21 | return email; 22 | } 23 | 24 | public void setEmail( final String email ) { 25 | this.email = email; 26 | } 27 | 28 | public String getFirstName() { 29 | return firstName; 30 | } 31 | 32 | public String getLastName() { 33 | return lastName; 34 | } 35 | 36 | public void setFirstName( final String firstName ) { 37 | this.firstName = firstName; 38 | } 39 | 40 | public void setLastName( final String lastName ) { 41 | this.lastName = lastName; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/java/com/example/rs/JaxRsApiApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.rs; 2 | 3 | import javax.ws.rs.ApplicationPath; 4 | import javax.ws.rs.core.Application; 5 | 6 | @ApplicationPath( "api" ) 7 | public class JaxRsApiApplication extends Application { 8 | } 9 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/java/com/example/rs/PeopleRestService.java: -------------------------------------------------------------------------------- 1 | package com.example.rs; 2 | 3 | import java.util.Collection; 4 | 5 | import javax.inject.Inject; 6 | import javax.ws.rs.DELETE; 7 | import javax.ws.rs.DefaultValue; 8 | import javax.ws.rs.FormParam; 9 | import javax.ws.rs.GET; 10 | import javax.ws.rs.POST; 11 | import javax.ws.rs.PUT; 12 | import javax.ws.rs.Path; 13 | import javax.ws.rs.PathParam; 14 | import javax.ws.rs.Produces; 15 | import javax.ws.rs.QueryParam; 16 | import javax.ws.rs.core.Context; 17 | import javax.ws.rs.core.MediaType; 18 | import javax.ws.rs.core.Response; 19 | import javax.ws.rs.core.UriInfo; 20 | 21 | import com.example.model.Person; 22 | import com.example.services.PeopleService; 23 | 24 | @Path("/people") 25 | public class PeopleRestService { 26 | @Inject 27 | private PeopleService peopleService; 28 | 29 | @Produces({ MediaType.APPLICATION_JSON }) 30 | @GET 31 | public Collection getPeopleList(@QueryParam("page") @DefaultValue("1") final int page) { 32 | return peopleService.getPeople(page, 5); 33 | } 34 | 35 | @Produces({ MediaType.APPLICATION_JSON }) 36 | @Path("/{email}") 37 | @GET 38 | public Person getPeople(@PathParam("email") final String email) { 39 | return peopleService.getByEmail(email); 40 | } 41 | 42 | @Produces({ MediaType.APPLICATION_JSON }) 43 | @POST 44 | public Response addPerson(@Context final UriInfo uriInfo, @FormParam("email") final String email, 45 | @FormParam("firstName") final String firstName, @FormParam("lastName") final String lastName) { 46 | 47 | peopleService.addPerson(email, firstName, lastName); 48 | return Response.created(uriInfo.getRequestUriBuilder().path(email).build()).build(); 49 | } 50 | 51 | @Produces({ MediaType.APPLICATION_JSON }) 52 | @Path("/{email}") 53 | @PUT 54 | public Person updatePerson(@PathParam("email") final String email, @FormParam("firstName") final String firstName, 55 | @FormParam("lastName") final String lastName) { 56 | 57 | final Person person = peopleService.getByEmail(email); 58 | 59 | if (firstName != null) { 60 | person.setFirstName(firstName); 61 | } 62 | 63 | if (lastName != null) { 64 | person.setLastName(lastName); 65 | } 66 | 67 | return person; 68 | } 69 | 70 | @Path("/{email}") 71 | @DELETE 72 | public Response deletePerson(@PathParam("email") final String email) { 73 | peopleService.removePerson(email); 74 | return Response.ok().build(); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/java/com/example/services/PeopleService.java: -------------------------------------------------------------------------------- 1 | package com.example.services; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.Iterator; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | import java.util.concurrent.ConcurrentMap; 8 | 9 | import org.springframework.stereotype.Service; 10 | 11 | import com.example.exceptions.PersonAlreadyExistsException; 12 | import com.example.exceptions.PersonNotFoundException; 13 | import com.example.model.Person; 14 | 15 | @Service 16 | public class PeopleService { 17 | private final ConcurrentMap< String, Person > persons = new ConcurrentHashMap< String, Person >(); 18 | 19 | public Collection< Person > getPeople( int page, int pageSize ) { 20 | final Collection< Person > slice = new ArrayList< Person >( pageSize ); 21 | 22 | final Iterator< Person > iterator = persons.values().iterator(); 23 | for( int i = 0; slice.size() < pageSize && iterator.hasNext(); ) { 24 | if( ++i > ( ( page - 1 ) * pageSize ) ) { 25 | slice.add( iterator.next() ); 26 | } 27 | } 28 | 29 | return slice; 30 | } 31 | 32 | public Person getByEmail( final String email ) { 33 | final Person person = persons.get( email ); 34 | 35 | if( person == null ) { 36 | throw new PersonNotFoundException( email ); 37 | } 38 | 39 | return person; 40 | } 41 | 42 | public Person addPerson( final String email, final String firstName, final String lastName ) { 43 | final Person person = new Person( email ); 44 | person.setFirstName( firstName ); 45 | person.setLastName( lastName ); 46 | 47 | if( persons.putIfAbsent( email, person ) != null ) { 48 | throw new PersonAlreadyExistsException( email ); 49 | } 50 | 51 | return person; 52 | } 53 | 54 | public void removePerson( final String email ) { 55 | if( persons.remove( email ) == null ) { 56 | throw new PersonNotFoundException( email ); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/resources/META-INF/cxf/org.apache.cxf.Logger: -------------------------------------------------------------------------------- 1 | org.apache.cxf.common.logging.Slf4jLogger -------------------------------------------------------------------------------- /sample-web-app-server/src/main/resources/WEB-INF/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Insert title here 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/resources/WEB-INF/js/People.js: -------------------------------------------------------------------------------- 1 | // java2ts module 2 | j2ts = { 3 | 4 | // -- Adapters for REST calls 5 | adapters : { 6 | 7 | // >> To console 8 | console: function(httpMethod, path, getParams, postParams, body) { 9 | console.log([httpMethod, path, getParams, postParams, body]); 10 | }, 11 | 12 | // >> Jquery 13 | jQuery : function jQueryAdapter(httpMethod, url, getParams, postParams, body) { 14 | var processData = true; 15 | var data; 16 | if (getParams != null) { 17 | // in URL 18 | data = getParams; 19 | } else if (postParams != null) { 20 | // as form Params 21 | data = postParams; 22 | } else if (body != null) { 23 | // as JSON in body 24 | data = JSON.stringify(body); 25 | processData = false; 26 | } 27 | 28 | jQuery.ajax({ 29 | type : httpMethod, 30 | url : url, 31 | processData : processData, 32 | data : data 33 | }).done(function(data) { 34 | console.log(data); 35 | }) 36 | } // end of jQuery adapter 37 | } // end of adapters 38 | 39 | } // end of j2ts module definition 40 | 41 | j2ts.buildModule = function(desc) { 42 | 43 | var outModule = { 44 | 45 | rootUrl : null, 46 | 47 | // JQuery by default 48 | adapter : j2ts.adapters.jQuery 49 | 50 | }; 51 | 52 | function methodGenerator(methodDesc) { 53 | 54 | return function() { 55 | 56 | if (outModule.rootUrl == null) { 57 | throw new Error("rootUrl is null, set it before calling rest methods"); 58 | } 59 | 60 | var url = outModule.rootUrl + desc.path + methodDesc.path 61 | 62 | // Init params to be passed to adapter function 63 | var getParams = null; 64 | var postParams = null; 65 | var body = null; 66 | 67 | // Loop on params 68 | for (var i=0; i< methodDesc.params.length; i++) { 69 | var paramValue = arguments[i]; 70 | var paramDesc = methodDesc.params[i]; 71 | 72 | switch(paramDesc.type) { 73 | case "FORM" : 74 | if (postParams == null) postParams = {}; 75 | postParams[paramDesc.name] = paramValue; 76 | break; 77 | case "QUERY" : 78 | if (getParams == null) getParams = {}; 79 | getParams[paramDesc.name] = paramValue; 80 | break; 81 | case "PATH" : 82 | url = url.replace("{" + paramDesc.name + "}", paramValue) 83 | break; 84 | case "BODY" : 85 | body = paramValue; 86 | } 87 | } 88 | 89 | // Actual call to the adapter 90 | outModule.adapter(methodDesc.httpMethod, url, getParams, postParams, body); 91 | } 92 | } 93 | 94 | // Dynamically add some methods to the module 95 | for (var methodName in desc.methods) { 96 | var methodDesc = desc.methods[methodName]; 97 | outModule[methodName] = methodGenerator(methodDesc); 98 | } 99 | 100 | return outModule; 101 | } 102 | 103 | People = j2ts.buildModule({ 104 | "name" : "PeopleRestService", 105 | "path" : "/people", 106 | "methods" : { 107 | "deletePerson" : { 108 | "path" : "/{email}", 109 | "params" : [ { 110 | "name" : "email", 111 | "type" : "PATH" 112 | } ], 113 | "httpMethod" : "DELETE" 114 | }, 115 | "getPeople" : { 116 | "path" : "/{email}", 117 | "params" : [ { 118 | "name" : "email", 119 | "type" : "PATH" 120 | } ], 121 | "httpMethod" : "GET" 122 | }, 123 | "addPerson" : { 124 | "path" : "", 125 | "params" : [ { 126 | "name" : "email", 127 | "type" : "FORM" 128 | }, { 129 | "name" : "firstName", 130 | "type" : "FORM" 131 | }, { 132 | "name" : "lastName", 133 | "type" : "FORM" 134 | } ], 135 | "httpMethod" : "POST" 136 | }, 137 | "updatePerson" : { 138 | "path" : "/{email}", 139 | "params" : [ { 140 | "name" : "email", 141 | "type" : "PATH" 142 | }, { 143 | "name" : "firstName", 144 | "type" : "FORM" 145 | }, { 146 | "name" : "lastName", 147 | "type" : "FORM" 148 | } ], 149 | "httpMethod" : "PUT" 150 | } 151 | } 152 | }); 153 | 154 | 155 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/resources/WEB-INF/js/PeopleApp.js: -------------------------------------------------------------------------------- 1 | var p = People; 2 | 3 | var prs = p.peopleRestService; 4 | 5 | p.rootUrl = "http://someurl/root/"; 6 | 7 | var personList = prs.getPeopleList(1); 8 | var onePerson = prs.getPeople("rrr@eee.com"); 9 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/resources/WEB-INF/ts/People.d.ts: -------------------------------------------------------------------------------- 1 | declare module People { 2 | 3 | export interface PeopleRestService { 4 | getPeopleList(page: number): Person[]; 5 | addPerson(email: string, firstName: string, lastName: string): any; 6 | updatePerson(email: string, firstName: string, lastName: string): Person; 7 | deletePerson(email: string): any; 8 | getPeople(email: string): Person; 9 | } 10 | 11 | export interface Person { 12 | email: string; 13 | firstName: string; 14 | lastName: string; 15 | } 16 | 17 | export var peopleRestService: PeopleRestService; 18 | export var adapter : (a: string) => void; 19 | export var rootUrl: Object; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /sample-web-app-server/src/main/resources/WEB-INF/ts/PeopleApp.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import p = People; 3 | import Person = p.Person; 4 | import prs = p.peopleRestService; 5 | 6 | p.rootUrl = "http://someurl/root/"; 7 | 8 | var personList : Person[] = prs.getPeopleList(1); 9 | var onePerson : Person = prs.getPeople("rrr@eee.com"); 10 | -------------------------------------------------------------------------------- /sample-web-app/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /.project 3 | /.classpath 4 | /.settings 5 | -------------------------------------------------------------------------------- /sample-web-app/README.md: -------------------------------------------------------------------------------- 1 | spring-one-jar 2 | ============== 3 | 4 | - curl http://localhost:8080/rest/api/people -X PUT -d "email=a@b.com" 5 | - curl http://localhost:8080/rest/api/people?page=2 6 | -------------------------------------------------------------------------------- /sample-web-app/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.github.raphaeljolivet.java2typescript 6 | java2typescript 7 | v0.3.2-SNAPSHOT 8 | 9 | 10 | sample-web-app 11 | jar 12 | 13 | 14 | UTF-8 15 | 2.7.2 16 | 3.2.0.RELEASE 17 | 8.1.8.v20121106 18 | 19 | 20 | 21 | 22 | org.apache.cxf 23 | cxf-rt-frontend-jaxrs 24 | ${org.apache.cxf.version} 25 | 26 | 27 | 28 | javax.inject 29 | javax.inject 30 | 1 31 | 32 | 33 | 34 | org.codehaus.jackson 35 | jackson-jaxrs 36 | 1.9.11 37 | 38 | 39 | 40 | org.codehaus.jackson 41 | jackson-mapper-asl 42 | 1.9.11 43 | 44 | 45 | 46 | cglib 47 | cglib-nodep 48 | 2.2 49 | 50 | 51 | 52 | org.springframework 53 | spring-core 54 | ${org.springframework.version} 55 | 56 | 57 | 58 | org.springframework 59 | spring-context 60 | ${org.springframework.version} 61 | 62 | 63 | 64 | org.springframework 65 | spring-web 66 | ${org.springframework.version} 67 | 68 | 69 | 70 | org.eclipse.jetty 71 | jetty-server 72 | ${org.eclipse.jetty.version} 73 | 74 | 75 | 76 | org.eclipse.jetty 77 | jetty-util 78 | ${org.eclipse.jetty.version} 79 | 80 | 81 | 82 | org.eclipse.jetty 83 | jetty-webapp 84 | ${org.eclipse.jetty.version} 85 | 86 | 87 | 88 | 89 | 90 | 91 | org.apache.maven.plugins 92 | maven-compiler-plugin 93 | 3.0 94 | 95 | 1.6 96 | 1.6 97 | 98 | 99 | 100 | com.github.raphaeljolivet.java2typescript 101 | java2typescript-maven-plugin 102 | v0.3.2-SNAPSHOT 103 | 104 | com.example.rs.PeopleRestService 105 | People 106 | 107 | 108 | 109 | org.apache.maven.plugins 110 | maven-jar-plugin 111 | 112 | 113 | 114 | com.example.Starter 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | maven2-repository.dev.java.net 125 | Java.net Repository for Maven 126 | http://download.java.net/maven/2/ 127 | default 128 | 129 | 130 | 131 | 132 | jitpack.io2 133 | jitpack.io Plugin Repository 134 | https://jitpack.io 135 | default 136 | 137 | true 138 | 139 | 140 | always 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /sample-web-app/src/main/java/com/example/Starter.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import java.io.IOException; 4 | import java.net.URISyntaxException; 5 | 6 | import org.apache.cxf.transport.servlet.CXFServlet; 7 | import org.eclipse.jetty.server.Server; 8 | import org.eclipse.jetty.server.handler.HandlerCollection; 9 | import org.eclipse.jetty.server.handler.ResourceHandler; 10 | import org.eclipse.jetty.servlet.ServletContextHandler; 11 | import org.eclipse.jetty.servlet.ServletHolder; 12 | import org.springframework.web.context.ContextLoaderListener; 13 | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; 14 | 15 | import com.example.config.AppConfig; 16 | 17 | public class Starter { 18 | public static void main(final String[] args) throws Exception { 19 | 20 | Server server = new Server(8080); 21 | HandlerCollection handlerCollection = new HandlerCollection(); 22 | server.setHandler(handlerCollection); 23 | 24 | addSpringContext(handlerCollection); 25 | 26 | // Default one, resourceHandler takes everything 27 | addStaticContext(handlerCollection); 28 | 29 | server.start(); 30 | server.join(); 31 | } 32 | 33 | static private void addSpringContext(HandlerCollection collection) { 34 | final ServletHolder servletHolder = new ServletHolder(new CXFServlet()); 35 | final ServletContextHandler context = new ServletContextHandler(); 36 | context.setContextPath("/"); 37 | 38 | context.addServlet(servletHolder, "/rest/*"); 39 | context.addEventListener(new ContextLoaderListener()); 40 | 41 | context.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName()); 42 | context.setInitParameter("contextConfigLocation", AppConfig.class.getName()); 43 | 44 | collection.addHandler(context); 45 | } 46 | 47 | static private void addStaticContext(HandlerCollection collection) { 48 | ResourceHandler resHandler = new ResourceHandler(); 49 | resHandler.setWelcomeFiles(new String[] { "index.html" }); 50 | try { 51 | resHandler.setBaseResource(new org.eclipse.jetty.util.resource.FileResource(Starter.class 52 | .getResource("/WEB-INF/"))); 53 | } 54 | catch (Exception e) { 55 | throw new RuntimeException(e); 56 | } 57 | collection.addHandler(resHandler); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /sample-web-app/src/main/java/com/example/config/AppConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.config; 2 | 3 | import java.util.Arrays; 4 | 5 | import javax.ws.rs.ext.RuntimeDelegate; 6 | 7 | import org.apache.cxf.bus.spring.SpringBus; 8 | import org.apache.cxf.endpoint.Server; 9 | import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; 10 | import org.codehaus.jackson.jaxrs.JacksonJsonProvider; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.context.annotation.DependsOn; 14 | 15 | import com.example.rs.JaxRsApiApplication; 16 | import com.example.rs.PeopleRestService; 17 | import com.example.services.PeopleService; 18 | 19 | @Configuration 20 | public class AppConfig { 21 | @Bean( destroyMethod = "shutdown" ) 22 | public SpringBus cxf() { 23 | return new SpringBus(); 24 | } 25 | 26 | @Bean @DependsOn( "cxf" ) 27 | public Server jaxRsServer() { 28 | JAXRSServerFactoryBean factory = RuntimeDelegate.getInstance().createEndpoint( jaxRsApiApplication(), JAXRSServerFactoryBean.class ); 29 | factory.setServiceBeans( Arrays.< Object >asList( peopleRestService() ) ); 30 | factory.setAddress( "/" + factory.getAddress() ); 31 | factory.setProviders( Arrays.< Object >asList( jsonProvider() ) ); 32 | return factory.create(); 33 | } 34 | 35 | @Bean 36 | public JaxRsApiApplication jaxRsApiApplication() { 37 | return new JaxRsApiApplication(); 38 | } 39 | 40 | @Bean 41 | public PeopleRestService peopleRestService() { 42 | return new PeopleRestService(); 43 | } 44 | 45 | @Bean 46 | public PeopleService peopleService() { 47 | return new PeopleService(); 48 | } 49 | 50 | @Bean 51 | public JacksonJsonProvider jsonProvider() { 52 | return new JacksonJsonProvider(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /sample-web-app/src/main/java/com/example/exceptions/PersonAlreadyExistsException.java: -------------------------------------------------------------------------------- 1 | package com.example.exceptions; 2 | 3 | import javax.ws.rs.WebApplicationException; 4 | import javax.ws.rs.core.Response; 5 | import javax.ws.rs.core.Response.Status; 6 | 7 | public class PersonAlreadyExistsException extends WebApplicationException { 8 | private static final long serialVersionUID = 6817489620338221395L; 9 | 10 | public PersonAlreadyExistsException( final String email ) { 11 | super( 12 | Response 13 | .status( Status.CONFLICT ) 14 | .entity( "Person already exists: " + email ) 15 | .build() 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample-web-app/src/main/java/com/example/exceptions/PersonNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.exceptions; 2 | 3 | import javax.ws.rs.WebApplicationException; 4 | import javax.ws.rs.core.Response; 5 | import javax.ws.rs.core.Response.Status; 6 | 7 | public class PersonNotFoundException extends WebApplicationException { 8 | private static final long serialVersionUID = -2894269137259898072L; 9 | 10 | public PersonNotFoundException( final String email ) { 11 | super( 12 | Response 13 | .status( Status.NOT_FOUND ) 14 | .entity( "Person not found: " + email ) 15 | .build() 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample-web-app/src/main/java/com/example/model/Person.java: -------------------------------------------------------------------------------- 1 | package com.example.model; 2 | 3 | public class Person { 4 | private String email; 5 | private String firstName; 6 | private String lastName; 7 | 8 | public Person() { 9 | } 10 | 11 | public Person( final String email ) { 12 | this.email = email; 13 | } 14 | 15 | public Person( final String firstName, final String lastName ) { 16 | this.firstName = firstName; 17 | this.lastName = lastName; 18 | } 19 | 20 | public String getEmail() { 21 | return email; 22 | } 23 | 24 | public void setEmail( final String email ) { 25 | this.email = email; 26 | } 27 | 28 | public String getFirstName() { 29 | return firstName; 30 | } 31 | 32 | public String getLastName() { 33 | return lastName; 34 | } 35 | 36 | public void setFirstName( final String firstName ) { 37 | this.firstName = firstName; 38 | } 39 | 40 | public void setLastName( final String lastName ) { 41 | this.lastName = lastName; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sample-web-app/src/main/java/com/example/rs/JaxRsApiApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.rs; 2 | 3 | import javax.ws.rs.ApplicationPath; 4 | import javax.ws.rs.core.Application; 5 | 6 | @ApplicationPath( "api" ) 7 | public class JaxRsApiApplication extends Application { 8 | } 9 | -------------------------------------------------------------------------------- /sample-web-app/src/main/java/com/example/rs/PeopleRestService.java: -------------------------------------------------------------------------------- 1 | package com.example.rs; 2 | 3 | import java.util.Collection; 4 | 5 | import javax.inject.Inject; 6 | import javax.ws.rs.DELETE; 7 | import javax.ws.rs.DefaultValue; 8 | import javax.ws.rs.FormParam; 9 | import javax.ws.rs.GET; 10 | import javax.ws.rs.POST; 11 | import javax.ws.rs.PUT; 12 | import javax.ws.rs.Path; 13 | import javax.ws.rs.PathParam; 14 | import javax.ws.rs.Produces; 15 | import javax.ws.rs.QueryParam; 16 | import javax.ws.rs.core.Context; 17 | import javax.ws.rs.core.MediaType; 18 | import javax.ws.rs.core.Response; 19 | import javax.ws.rs.core.UriInfo; 20 | 21 | import com.example.model.Person; 22 | import com.example.services.PeopleService; 23 | 24 | @Path("/people") 25 | public class PeopleRestService { 26 | @Inject 27 | private PeopleService peopleService; 28 | 29 | @Produces({ MediaType.APPLICATION_JSON }) 30 | @GET 31 | public Collection getPeopleList(@QueryParam("page") @DefaultValue("1") final int page) { 32 | return peopleService.getPeople(page, 5); 33 | } 34 | 35 | @Produces({ MediaType.APPLICATION_JSON }) 36 | @Path("/{email}") 37 | @GET 38 | public Person getPeople(@PathParam("email") final String email) { 39 | return peopleService.getByEmail(email); 40 | } 41 | 42 | @Produces({ MediaType.APPLICATION_JSON }) 43 | @POST 44 | public Response addPerson(@Context final UriInfo uriInfo, @FormParam("email") final String email, 45 | @FormParam("firstName") final String firstName, @FormParam("lastName") final String lastName) { 46 | 47 | peopleService.addPerson(email, firstName, lastName); 48 | return Response.created(uriInfo.getRequestUriBuilder().path(email).build()).build(); 49 | } 50 | 51 | @Produces({ MediaType.APPLICATION_JSON }) 52 | @Path("/{email}") 53 | @PUT 54 | public Person updatePerson(@PathParam("email") final String email, @FormParam("firstName") final String firstName, 55 | @FormParam("lastName") final String lastName) { 56 | 57 | final Person person = peopleService.getByEmail(email); 58 | 59 | if (firstName != null) { 60 | person.setFirstName(firstName); 61 | } 62 | 63 | if (lastName != null) { 64 | person.setLastName(lastName); 65 | } 66 | 67 | return person; 68 | } 69 | 70 | @Path("/{email}") 71 | @DELETE 72 | public Response deletePerson(@PathParam("email") final String email) { 73 | peopleService.removePerson(email); 74 | return Response.ok().build(); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /sample-web-app/src/main/java/com/example/services/PeopleService.java: -------------------------------------------------------------------------------- 1 | package com.example.services; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.Iterator; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | import java.util.concurrent.ConcurrentMap; 8 | 9 | import org.springframework.stereotype.Service; 10 | 11 | import com.example.exceptions.PersonAlreadyExistsException; 12 | import com.example.exceptions.PersonNotFoundException; 13 | import com.example.model.Person; 14 | 15 | @Service 16 | public class PeopleService { 17 | private final ConcurrentMap< String, Person > persons = new ConcurrentHashMap< String, Person >(); 18 | 19 | public Collection< Person > getPeople( int page, int pageSize ) { 20 | final Collection< Person > slice = new ArrayList< Person >( pageSize ); 21 | 22 | final Iterator< Person > iterator = persons.values().iterator(); 23 | for( int i = 0; slice.size() < pageSize && iterator.hasNext(); ) { 24 | if( ++i > ( ( page - 1 ) * pageSize ) ) { 25 | slice.add( iterator.next() ); 26 | } 27 | } 28 | 29 | return slice; 30 | } 31 | 32 | public Person getByEmail( final String email ) { 33 | final Person person = persons.get( email ); 34 | 35 | if( person == null ) { 36 | throw new PersonNotFoundException( email ); 37 | } 38 | 39 | return person; 40 | } 41 | 42 | public Person addPerson( final String email, final String firstName, final String lastName ) { 43 | final Person person = new Person( email ); 44 | person.setFirstName( firstName ); 45 | person.setLastName( lastName ); 46 | 47 | if( persons.putIfAbsent( email, person ) != null ) { 48 | throw new PersonAlreadyExistsException( email ); 49 | } 50 | 51 | return person; 52 | } 53 | 54 | public void removePerson( final String email ) { 55 | if( persons.remove( email ) == null ) { 56 | throw new PersonNotFoundException( email ); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /sample-web-app/src/main/resources/META-INF/cxf/org.apache.cxf.Logger: -------------------------------------------------------------------------------- 1 | org.apache.cxf.common.logging.Slf4jLogger -------------------------------------------------------------------------------- /sample-web-app/src/main/resources/WEB-INF/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Insert title here 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sample-web-app/src/main/resources/WEB-INF/js/People.js: -------------------------------------------------------------------------------- 1 | // java2ts module 2 | j2ts = { 3 | 4 | // -- Adapters for REST calls 5 | adapters : { 6 | 7 | // >> To console 8 | console: function(httpMethod, path, getParams, postParams, body) { 9 | console.log([httpMethod, path, getParams, postParams, body]); 10 | }, 11 | 12 | // >> Jquery 13 | jQuery : function jQueryAdapter(httpMethod, url, getParams, postParams, body) { 14 | var processData = true; 15 | var data; 16 | if (getParams != null) { 17 | // in URL 18 | data = getParams; 19 | } else if (postParams != null) { 20 | // as form Params 21 | data = postParams; 22 | } else if (body != null) { 23 | // as JSON in body 24 | data = JSON.stringify(body); 25 | processData = false; 26 | } 27 | 28 | jQuery.ajax({ 29 | type : httpMethod, 30 | url : url, 31 | processData : processData, 32 | data : data 33 | }).done(function(data) { 34 | console.log(data); 35 | }) 36 | } // end of jQuery adapter 37 | } // end of adapters 38 | 39 | } // end of j2ts module definition 40 | 41 | j2ts.buildModule = function(desc) { 42 | 43 | var outModule = { 44 | 45 | rootUrl : null, 46 | 47 | // JQuery by default 48 | adapter : j2ts.adapters.jQuery 49 | 50 | }; 51 | 52 | function methodGenerator(methodDesc) { 53 | 54 | return function() { 55 | 56 | if (outModule.rootUrl == null) { 57 | throw new Error("rootUrl is null, set it before calling rest methods"); 58 | } 59 | 60 | var url = outModule.rootUrl + desc.path + methodDesc.path 61 | 62 | // Init params to be passed to adapter function 63 | var getParams = null; 64 | var postParams = null; 65 | var body = null; 66 | 67 | // Loop on params 68 | for (var i=0; i< methodDesc.params.length; i++) { 69 | var paramValue = arguments[i]; 70 | var paramDesc = methodDesc.params[i]; 71 | 72 | switch(paramDesc.type) { 73 | case "FORM" : 74 | if (postParams == null) postParams = {}; 75 | postParams[paramDesc.name] = paramValue; 76 | break; 77 | case "QUERY" : 78 | if (getParams == null) getParams = {}; 79 | getParams[paramDesc.name] = paramValue; 80 | break; 81 | case "PATH" : 82 | url = url.replace("{" + paramDesc.name + "}", paramValue) 83 | break; 84 | case "BODY" : 85 | body = paramValue; 86 | } 87 | } 88 | 89 | // Actual call to the adapter 90 | outModule.adapter(methodDesc.httpMethod, url, getParams, postParams, body); 91 | } 92 | } 93 | 94 | // Dynamically add some methods to the module 95 | for (var methodName in desc.methods) { 96 | var methodDesc = desc.methods[methodName]; 97 | outModule[methodName] = methodGenerator(methodDesc); 98 | } 99 | 100 | return outModule; 101 | } 102 | 103 | People = j2ts.buildModule({ 104 | "name" : "PeopleRestService", 105 | "path" : "/people", 106 | "methods" : { 107 | "deletePerson" : { 108 | "path" : "/{email}", 109 | "params" : [ { 110 | "name" : "email", 111 | "type" : "PATH" 112 | } ], 113 | "httpMethod" : "DELETE" 114 | }, 115 | "getPeople" : { 116 | "path" : "/{email}", 117 | "params" : [ { 118 | "name" : "email", 119 | "type" : "PATH" 120 | } ], 121 | "httpMethod" : "GET" 122 | }, 123 | "addPerson" : { 124 | "path" : "", 125 | "params" : [ { 126 | "name" : "email", 127 | "type" : "FORM" 128 | }, { 129 | "name" : "firstName", 130 | "type" : "FORM" 131 | }, { 132 | "name" : "lastName", 133 | "type" : "FORM" 134 | } ], 135 | "httpMethod" : "POST" 136 | }, 137 | "updatePerson" : { 138 | "path" : "/{email}", 139 | "params" : [ { 140 | "name" : "email", 141 | "type" : "PATH" 142 | }, { 143 | "name" : "firstName", 144 | "type" : "FORM" 145 | }, { 146 | "name" : "lastName", 147 | "type" : "FORM" 148 | } ], 149 | "httpMethod" : "PUT" 150 | } 151 | } 152 | }); 153 | 154 | 155 | -------------------------------------------------------------------------------- /sample-web-app/src/main/resources/WEB-INF/js/PeopleApp.js: -------------------------------------------------------------------------------- 1 | var p = People; 2 | 3 | var prs = p.peopleRestService; 4 | 5 | p.rootUrl = "http://someurl/root/"; 6 | 7 | var personList = prs.getPeopleList(1); 8 | var onePerson = prs.getPeople("rrr@eee.com"); 9 | -------------------------------------------------------------------------------- /sample-web-app/src/main/resources/WEB-INF/ts/People.d.ts: -------------------------------------------------------------------------------- 1 | declare module People { 2 | 3 | export interface PeopleRestService { 4 | getPeopleList(page: number): Person[]; 5 | addPerson(email: string, firstName: string, lastName: string): any; 6 | updatePerson(email: string, firstName: string, lastName: string): Person; 7 | deletePerson(email: string): any; 8 | getPeople(email: string): Person; 9 | } 10 | 11 | export interface Person { 12 | email: string; 13 | firstName: string; 14 | lastName: string; 15 | } 16 | 17 | export var peopleRestService: PeopleRestService; 18 | export var adapter : (a: string) => void; 19 | export var rootUrl: Object; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /sample-web-app/src/main/resources/WEB-INF/ts/PeopleApp.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import p = People; 3 | import Person = p.Person; 4 | import prs = p.peopleRestService; 5 | 6 | p.rootUrl = "http://someurl/root/"; 7 | 8 | var personList : Person[] = prs.getPeopleList(1); 9 | var onePerson : Person = prs.getPeople("rrr@eee.com"); 10 | --------------------------------------------------------------------------------