-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide Maven plugin for generating TypeScript DTO objects based on Java DTO #2490
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
|
||
Copyright (c) 2012-2016 Codenvy, S.A. | ||
All rights reserved. This program and the accompanying materials | ||
are made available under the terms of the Eclipse Public License v1.0 | ||
which accompanies this distribution, and is available at | ||
http://www.eclipse.org/legal/epl-v10.html | ||
|
||
Contributors: | ||
Codenvy, S.A. - initial API and implementation | ||
|
||
--> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<artifactId>che-core-parent</artifactId> | ||
<groupId>org.eclipse.che.core</groupId> | ||
<version>5.0.0-M2-SNAPSHOT</version> | ||
</parent> | ||
<groupId>org.eclipse.che.core</groupId> | ||
<artifactId>che-core-typescript-dto-maven-plugin</artifactId> | ||
<packaging>maven-plugin</packaging> | ||
<name>Che Core :: API :: TypeScript DTO maven plugin</name> | ||
<dependencies> | ||
<dependency> | ||
<groupId>com.google.code.gson</groupId> | ||
<artifactId>gson</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.antlr</groupId> | ||
<artifactId>ST4</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.che.core</groupId> | ||
<artifactId>che-core-api-dto</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.reflections</groupId> | ||
<artifactId>reflections</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-artifact</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-model</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-plugin-api</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven.plugin-tools</groupId> | ||
<artifactId>maven-plugin-annotations</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.sisu</groupId> | ||
<artifactId>org.eclipse.sisu.plexus</artifactId> | ||
<scope>provided</scope> | ||
<exclusions> | ||
<exclusion> | ||
<artifactId>jsr250-api</artifactId> | ||
<groupId>javax.annotation</groupId> | ||
</exclusion> | ||
</exclusions> | ||
</dependency> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-compat</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven.plugin-testing</groupId> | ||
<artifactId>maven-plugin-testing-harness</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.codehaus.plexus</groupId> | ||
<artifactId>plexus-utils</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.mockito</groupId> | ||
<artifactId>mockito-all</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-plugin-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<id>mojo-descriptor</id> | ||
<goals> | ||
<goal>descriptor</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
<configuration> | ||
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
155 changes: 155 additions & 0 deletions
155
...cript-dto-maven-plugin/src/main/java/org/eclipse/che/plugin/typescript/dto/DTOHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2012-2016 Codenvy, S.A. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Codenvy, S.A. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.che.plugin.typescript.dto; | ||
|
||
import org.eclipse.che.dto.shared.DelegateTo; | ||
|
||
import java.lang.reflect.Method; | ||
import java.lang.reflect.ParameterizedType; | ||
import java.lang.reflect.Type; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* Helper class | ||
* | ||
* @author Florent Benoit | ||
*/ | ||
public class DTOHelper { | ||
|
||
/** | ||
* Utility class. | ||
*/ | ||
private DTOHelper() { | ||
|
||
} | ||
|
||
/** | ||
* Check is specified method is DTO getter. | ||
*/ | ||
public static boolean isDtoGetter(Method method) { | ||
if (method.isAnnotationPresent(DelegateTo.class)) { | ||
return false; | ||
} | ||
|
||
if (method.getParameterTypes().length > 0) { | ||
return false; | ||
} | ||
|
||
String methodName = method.getName(); | ||
|
||
return methodName.startsWith("get") || | ||
(methodName.startsWith("is") && ((method.getReturnType() == Boolean.class || method.getReturnType() == boolean.class))); | ||
|
||
} | ||
|
||
|
||
/** | ||
* Check is specified method is DTO setter. | ||
*/ | ||
public static boolean isDtoSetter(Method method) { | ||
if (method.isAnnotationPresent(DelegateTo.class)) { | ||
return false; | ||
} | ||
String methodName = method.getName(); | ||
return methodName.startsWith("set") && method.getParameterTypes().length == 1; | ||
} | ||
|
||
/** | ||
* Check is specified method is DTO with. | ||
*/ | ||
public static boolean isDtoWith(Method method) { | ||
if (method.isAnnotationPresent(DelegateTo.class)) { | ||
return false; | ||
} | ||
String methodName = method.getName(); | ||
return methodName.startsWith("with") && method.getParameterTypes().length == 1; | ||
} | ||
|
||
/** | ||
* Compute field name from the stringified string type | ||
*/ | ||
public static String getFieldName(String type) { | ||
char[] c = type.toCharArray(); | ||
c[0] = Character.toLowerCase(c[0]); | ||
return new String(c); | ||
} | ||
|
||
/** | ||
* Extract field name from the getter method | ||
*/ | ||
public static String getGetterFieldName(Method method) { | ||
String methodName = method.getName(); | ||
if (methodName.startsWith("get")) { | ||
return getFieldName(methodName.substring(3)); | ||
} else if (methodName.startsWith("is")) { | ||
return getFieldName(methodName.substring(2)); | ||
} | ||
throw new IllegalArgumentException("Invalid getter method" + method.getName()); | ||
} | ||
|
||
/** | ||
* Extract field name from the setter method | ||
*/ | ||
public static String getSetterFieldName(Method method) { | ||
String methodName = method.getName(); | ||
if (methodName.startsWith("set")) { | ||
return getFieldName(methodName.substring(3)); | ||
} | ||
throw new IllegalArgumentException("Invalid setter method" + method.getName()); | ||
} | ||
|
||
/** | ||
* Extract field name from the with method | ||
*/ | ||
public static String getWithFieldName(Method method) { | ||
String methodName = method.getName(); | ||
if (methodName.startsWith("with")) { | ||
return getFieldName(methodName.substring(4)); | ||
} | ||
throw new IllegalArgumentException("Invalid with method" + method.getName()); | ||
} | ||
|
||
/** | ||
* Convert Java type to TypeScript type | ||
*/ | ||
public static String convertType(Type type) { | ||
if (type instanceof ParameterizedType) { | ||
ParameterizedType parameterizedType = (ParameterizedType)type; | ||
Type rawType = parameterizedType.getRawType(); | ||
return convertParametrizedType(type, parameterizedType, rawType); | ||
} else if (String.class.equals(type) || (type instanceof Class && ((Class)type).isEnum())) { | ||
// Maybe find a better enum type for typescript | ||
return "string"; | ||
} else if (Integer.class.equals(type) || Integer.TYPE.equals(type) || Long.class.equals(type) || Long.TYPE.equals(type)) { | ||
return "number"; | ||
} else if (Boolean.class.equals(type)) { | ||
return "boolean"; | ||
} | ||
|
||
return type.getTypeName(); | ||
} | ||
|
||
/** | ||
* Handle convert of a parametrized Java type to TypeScript type | ||
*/ | ||
public static String convertParametrizedType(Type type, ParameterizedType parameterizedType, Type rawType) { | ||
|
||
if (List.class.equals(rawType)) { | ||
return "Array<" + convertType(parameterizedType.getActualTypeArguments()[0]) + ">"; | ||
} else if (Map.class.equals(rawType)) { | ||
return "Map<" + convertType(parameterizedType.getActualTypeArguments()[0]) + "," + | ||
convertType(parameterizedType.getActualTypeArguments()[1]) + ">"; | ||
} else { | ||
throw new IllegalArgumentException("Invalid type" + type); | ||
} | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
...lugin/src/main/java/org/eclipse/che/plugin/typescript/dto/TypeScriptDTOGeneratorMojo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2012-2016 Codenvy, S.A. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Codenvy, S.A. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.che.plugin.typescript.dto; | ||
|
||
import org.apache.maven.plugin.AbstractMojo; | ||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.apache.maven.plugin.MojoFailureException; | ||
import org.apache.maven.plugins.annotations.Component; | ||
import org.apache.maven.plugins.annotations.LifecyclePhase; | ||
import org.apache.maven.plugins.annotations.Mojo; | ||
import org.apache.maven.plugins.annotations.Parameter; | ||
import org.apache.maven.plugins.annotations.ResolutionScope; | ||
import org.apache.maven.project.MavenProject; | ||
import org.apache.maven.project.MavenProjectHelper; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.Writer; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
|
||
/** | ||
* Mojo for generating TypeScript DTO interface + implementation for handling JSON data. | ||
* @author Florent Benoit | ||
*/ | ||
@Mojo(name = "build", | ||
defaultPhase = LifecyclePhase.PACKAGE, | ||
requiresProject = true, | ||
requiresDependencyCollection = ResolutionScope.RUNTIME) | ||
public class TypeScriptDTOGeneratorMojo extends AbstractMojo { | ||
|
||
/** | ||
* Project providing artifact id, version and dependencies. | ||
*/ | ||
@Parameter(defaultValue = "${project}", readonly = true) | ||
private MavenProject project; | ||
|
||
/** | ||
* build directory used to write the intermediate bom file. | ||
*/ | ||
@Parameter(defaultValue = "${project.build.directory}") | ||
private File targetDirectory; | ||
|
||
@Component | ||
private MavenProjectHelper projectHelper; | ||
|
||
/** | ||
* Path to the generated typescript file | ||
*/ | ||
private File typescriptFile; | ||
|
||
/** | ||
* Use of classpath instead of classloader | ||
*/ | ||
private boolean useClassPath; | ||
|
||
@Override | ||
public void execute() throws MojoExecutionException, MojoFailureException { | ||
|
||
getLog().info("Generating TypeScript DTO"); | ||
|
||
TypeScriptDtoGenerator typeScriptDtoGenerator = new TypeScriptDtoGenerator(); | ||
|
||
typeScriptDtoGenerator.setUseClassPath(useClassPath); | ||
|
||
// define output path for the file to write with typescript definition | ||
String output = typeScriptDtoGenerator.execute(); | ||
|
||
this.typescriptFile = new File(targetDirectory, project.getArtifactId() + ".ts"); | ||
File parentDir = this.typescriptFile.getParentFile(); | ||
if (!parentDir.exists() && !parentDir.mkdirs()) { | ||
throw new MojoExecutionException("Unable to create a directory for writing DTO typescript file '" + parentDir + "'."); | ||
} | ||
|
||
try (Writer fileWriter = Files.newBufferedWriter(this.typescriptFile.toPath(), StandardCharsets.UTF_8)) { | ||
fileWriter.write(output); | ||
} catch (IOException e) { | ||
throw new MojoExecutionException("Cannot write DTO typescript file"); | ||
} | ||
|
||
// attach this typescript file as maven artifact | ||
projectHelper.attachArtifact(project, "ts", typescriptFile); | ||
} | ||
|
||
/** | ||
* Gets the TypeScript generated file | ||
* @return the generated file TypeScript link | ||
*/ | ||
public File getTypescriptFile() { | ||
return typescriptFile; | ||
} | ||
|
||
/** | ||
* Allow to configure generator to use classpath instead of classloader | ||
* @param useClassPath true if want to use classpath loading | ||
*/ | ||
public void setUseClassPath(boolean useClassPath) { | ||
this.useClassPath = useClassPath; | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provide more detailed javadoc for this helper class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hum ok I will provide a new PR then as it has been merged