/*******************************************************************************
* Copyright (c) 2012-2017 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 com.google.common.io.Resources;
import org.eclipse.che.dto.shared.DTO;
import org.eclipse.che.plugin.typescript.dto.model.DtoModel;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ConfigurationBuilder;
import org.stringtemplate.v4.ST;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.reflections.util.ClasspathHelper.forClassLoader;
import static org.reflections.util.ClasspathHelper.forJavaClassPath;
/**
* Write all DTOs found in classpath into a specific file. It will contains both DTO interface and DTO implementation.
* It will generate TypeScript code
* @author Florent Benoit
*/
public class TypeScriptDtoGenerator {
/**
* Name of the template
*/
public static final String TEMPLATE_NAME = "/".concat(TypeScriptDtoGenerator.class.getPackage().getName().replace(".", "/")).concat("/typescript.template");
/**
* String template instance used
*/
private ST st;
/**
* Model of DTOs that will be provided to the String Template
*/
private List<DtoModel> dtoModels;
/**
* Use of classpath
*/
private boolean useClassPath;
/**
* Setup a new generator
*/
public TypeScriptDtoGenerator() {
this.dtoModels = new ArrayList<>();
}
public static void main(String[] args) {
new TypeScriptDtoGenerator().execute();
}
/**
* Init stuff is responsible to grab all DTOs found in classpath (classloader) and setup model for String Template
*/
protected void init() {
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder().setScanners(new SubTypesScanner(), new TypeAnnotationsScanner());
if (useClassPath) {
configurationBuilder.setUrls(forJavaClassPath());
} else {
configurationBuilder.setUrls(forClassLoader());
}
// keep only DTO interfaces
Reflections reflections = new Reflections(configurationBuilder);
List<Class<?>> annotatedWithDtos = new ArrayList<>(reflections.getTypesAnnotatedWith(DTO.class));
List<Class<?>> interfacesDtos = annotatedWithDtos.stream()
.filter(clazz -> clazz.isInterface())
.collect(Collectors.toList());
interfacesDtos.stream().forEach(this::analyze);
}
/**
* Analyze a DTO interface by registering the associate model.
* @param dto the DTO to analyze
*/
protected void analyze(Class<?> dto) {
// for each dto class, store some data about it
this.dtoModels.add(new DtoModel(dto));
}
/**
* Execute this generator.
*/
public String execute() {
init();
ST template = getTemplate();
template.add("dtos", this.dtoModels);
String output = template.render();
return output;
}
/**
* Get the template for typescript
* @return the String Template
*/
protected ST getTemplate() {
if (st == null) {
URL url = Resources.getResource(TypeScriptDtoGenerator.class, TEMPLATE_NAME);
try {
st = new ST(Resources.toString(url, UTF_8));
} catch (IOException e) {
throw new IllegalArgumentException("Unable to read template", e);
}
}
return st;
}
public void setUseClassPath(boolean useClassPath) {
this.useClassPath = useClassPath;
}
}