2013-08-04 13:50:06 +01:00
|
|
|
package app
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
@Grab('spring-boot-starter-actuator')
|
|
|
|
@Grab('org.codehaus.groovy:groovy-ant:2.3.2')
|
2013-06-06 08:40:10 +01:00
|
|
|
|
|
|
|
@Controller
|
|
|
|
@Log
|
|
|
|
class MainController {
|
|
|
|
|
|
|
|
@Value('${info.home:http://localhost:8080/}')
|
|
|
|
private String home
|
|
|
|
|
2014-05-29 16:26:47 +01:00
|
|
|
@Value('${info.spring-boot.version:1.0.2.RELEASE}')
|
2014-04-01 17:22:18 +01:00
|
|
|
private String bootVersion
|
|
|
|
|
2013-06-06 08:40:10 +01:00
|
|
|
@Value('${TMPDIR:.}')
|
|
|
|
private String tmpdir
|
|
|
|
|
2013-08-04 13:50:06 +01:00
|
|
|
@Autowired
|
|
|
|
private Reactor reactor
|
|
|
|
|
2014-05-28 19:25:35 +01:00
|
|
|
@Autowired
|
|
|
|
private Projects projects
|
|
|
|
|
2014-05-30 09:50:24 +01:00
|
|
|
@RequestMapping(value='/')
|
|
|
|
@ResponseBody
|
|
|
|
Projects projects() {
|
|
|
|
projects
|
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value='/', produces='text/html')
|
2013-06-06 08:40:10 +01:00
|
|
|
@ResponseBody
|
|
|
|
String home() {
|
|
|
|
def model = [:]
|
2014-05-28 19:25:35 +01:00
|
|
|
// sort lists
|
2014-05-29 09:17:39 +01:00
|
|
|
model['styles'] = projects.styles.sort { it.name }
|
|
|
|
model['types'] = projects.types.sort { it.name }
|
2014-05-29 16:26:47 +01:00
|
|
|
model['packagings'] = projects.packagings.sort { it.name }
|
2014-05-30 06:18:33 +01:00
|
|
|
model['javaVersions'] = projects.javaVersions
|
2014-05-30 09:50:24 +01:00
|
|
|
model['languages'] = projects.languages
|
2014-05-29 09:17:39 +01:00
|
|
|
template 'home.html', model
|
2013-06-06 08:40:10 +01:00
|
|
|
}
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
@RequestMapping('/spring')
|
2013-06-06 08:40:10 +01:00
|
|
|
@ResponseBody
|
|
|
|
ResponseEntity<byte[]> spring() {
|
2014-05-29 09:17:39 +01:00
|
|
|
File download = new File(tmpdir, 'spring.zip')
|
2013-06-06 08:40:10 +01:00
|
|
|
if (!download.exists()) {
|
2014-05-29 09:17:39 +01:00
|
|
|
log.info('Creating: ' + download)
|
2013-06-06 08:40:10 +01:00
|
|
|
new AntBuilder().zip(destfile: download) {
|
2014-05-29 09:17:39 +01:00
|
|
|
zipfileset(dir:'.', includes:'spring/bin/**', filemode:'775')
|
|
|
|
zipfileset(dir:'.', includes:'spring/**', excludes:'spring/bin/**')
|
2013-06-06 08:40:10 +01:00
|
|
|
}
|
|
|
|
}
|
2014-05-29 16:26:47 +01:00
|
|
|
log.info('Uploading: ' + download)
|
2014-05-29 09:17:39 +01:00
|
|
|
new ResponseEntity<byte[]>(download.bytes, ['Content-Type':'application/zip'] as HttpHeaders, HttpStatus.OK)
|
2013-06-06 08:40:10 +01:00
|
|
|
}
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
@RequestMapping(value='/starter.tgz', produces='application/x-compress')
|
2013-07-22 14:40:50 +01:00
|
|
|
@ResponseBody
|
2014-04-01 19:46:00 +01:00
|
|
|
ResponseEntity<byte[]> springTgz(PomRequest request) {
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
File dir = File.createTempFile('tmp','',new File(tmpdir));
|
2014-04-01 19:46:00 +01:00
|
|
|
def tempFiles = getProjectFiles(dir, request)
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
File download = new File(tmpdir, dir.name + '.tgz')
|
|
|
|
log.info('Creating: ' + download)
|
2014-04-01 19:46:00 +01:00
|
|
|
tempFiles << download
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
new AntBuilder().tar(destfile: download, compression: 'gzip') {
|
|
|
|
zipfileset(dir:dir, includes:'**')
|
2014-04-01 19:46:00 +01:00
|
|
|
}
|
2014-05-29 09:17:39 +01:00
|
|
|
log.info("Uploading: ${download} (${download.bytes.length} bytes)")
|
|
|
|
def result = new ResponseEntity<byte[]>(download.bytes, ['Content-Type':'application/x-compress'] as HttpHeaders, HttpStatus.OK)
|
2014-04-01 19:46:00 +01:00
|
|
|
|
2014-05-29 16:26:47 +01:00
|
|
|
log.fine('Notifying reactor: ' + download)
|
2014-05-29 09:17:39 +01:00
|
|
|
reactor.notify('tempfiles', Event.wrap(tempFiles))
|
2014-04-01 19:46:00 +01:00
|
|
|
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
@RequestMapping('/starter.zip')
|
2014-04-01 19:46:00 +01:00
|
|
|
@ResponseBody
|
|
|
|
ResponseEntity<byte[]> springZip(PomRequest request) {
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
File dir = File.createTempFile('tmp','',new File(tmpdir));
|
2014-04-01 19:46:00 +01:00
|
|
|
def tempFiles = getProjectFiles(dir, request)
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
File download = new File(tmpdir, dir.name + '.zip')
|
|
|
|
log.info('Creating: ' + download)
|
2014-04-01 19:46:00 +01:00
|
|
|
tempFiles << download
|
|
|
|
|
|
|
|
new AntBuilder().zip(destfile: download) {
|
2014-05-29 09:17:39 +01:00
|
|
|
zipfileset(dir:dir, includes:'**')
|
2014-04-01 19:46:00 +01:00
|
|
|
}
|
2014-05-29 09:17:39 +01:00
|
|
|
log.info("Uploading: ${download} (${download.bytes.length} bytes)")
|
|
|
|
def result = new ResponseEntity<byte[]>(download.bytes, ['Content-Type':'application/zip'] as HttpHeaders, HttpStatus.OK)
|
2014-04-01 19:46:00 +01:00
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
log.info('Notifying reactor: ' + download)
|
|
|
|
reactor.notify('tempfiles', Event.wrap(tempFiles))
|
2014-04-01 19:46:00 +01:00
|
|
|
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2014-05-29 16:26:47 +01:00
|
|
|
def getProjectFiles(File dir, PomRequest request) {
|
2013-07-22 14:40:50 +01:00
|
|
|
|
2013-08-04 13:50:06 +01:00
|
|
|
def tempFiles = []
|
|
|
|
|
2013-07-22 14:40:50 +01:00
|
|
|
def model = [:]
|
2013-08-04 13:50:06 +01:00
|
|
|
tempFiles << dir
|
2013-07-22 14:40:50 +01:00
|
|
|
dir.delete()
|
|
|
|
dir.mkdirs()
|
2014-04-01 19:46:00 +01:00
|
|
|
|
2014-05-29 16:26:47 +01:00
|
|
|
if (request.type.contains('gradle')) {
|
|
|
|
String gradle = new String(gradle(request, model).body)
|
|
|
|
new File(dir, 'build.gradle').write(gradle)
|
|
|
|
} else {
|
|
|
|
String pom = new String(pom(request, model).body)
|
|
|
|
new File(dir, 'pom.xml').write(pom)
|
|
|
|
}
|
2014-04-01 19:46:00 +01:00
|
|
|
|
2014-05-30 09:50:24 +01:00
|
|
|
String language = request.language
|
|
|
|
|
|
|
|
File src = new File(new File(dir, 'src/main/' + language),request.packageName.replace('.', '/'))
|
2013-07-22 14:40:50 +01:00
|
|
|
src.mkdirs()
|
2014-05-30 09:50:24 +01:00
|
|
|
write(src, 'Application.' + language, model)
|
2014-05-29 16:26:47 +01:00
|
|
|
|
|
|
|
if (request.packaging=='war') {
|
2014-05-30 09:50:24 +01:00
|
|
|
write(src, 'ServletInitializer.' + language, model)
|
2014-05-29 16:26:47 +01:00
|
|
|
}
|
2013-07-22 14:40:50 +01:00
|
|
|
|
2014-05-30 09:50:24 +01:00
|
|
|
File test = new File(new File(dir, 'src/test/' + language),request.packageName.replace('.', '/'))
|
2013-11-01 14:39:56 +00:00
|
|
|
test.mkdirs()
|
2014-05-29 09:17:39 +01:00
|
|
|
if (model.styles.contains('-web')) {
|
|
|
|
model.testAnnotations = '@WebAppConfiguration\n'
|
|
|
|
model.testImports = 'import org.springframework.test.context.web.WebAppConfiguration;\n'
|
2014-03-18 10:21:31 +00:00
|
|
|
} else {
|
2014-05-29 09:17:39 +01:00
|
|
|
model.testAnnotations = ''
|
|
|
|
model.testImports = ''
|
2014-03-18 10:21:31 +00:00
|
|
|
}
|
2014-05-30 09:50:24 +01:00
|
|
|
write(test, 'ApplicationTests.' + language, model)
|
2013-11-01 14:39:56 +00:00
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
File resources = new File(dir, 'src/main/resources')
|
2014-04-01 08:57:06 +01:00
|
|
|
resources.mkdirs()
|
2014-05-29 09:17:39 +01:00
|
|
|
new File(resources, 'application.properties').write('')
|
2014-04-01 08:57:06 +01:00
|
|
|
|
2014-04-01 19:46:00 +01:00
|
|
|
tempFiles
|
2013-07-22 14:40:50 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-11-01 14:39:56 +00:00
|
|
|
def write(File src, String name, def model) {
|
2014-05-29 09:17:39 +01:00
|
|
|
log.info('Creating: ' + src + '/' + name)
|
2014-03-18 10:21:31 +00:00
|
|
|
def body = template name, model
|
2013-11-01 14:39:56 +00:00
|
|
|
new File(src, name).write(body)
|
|
|
|
}
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
@RequestMapping('/pom')
|
2013-06-06 08:40:10 +01:00
|
|
|
@ResponseBody
|
2013-07-22 14:40:50 +01:00
|
|
|
ResponseEntity<byte[]> pom(PomRequest request, Map model) {
|
2014-04-01 17:22:18 +01:00
|
|
|
model.bootVersion = bootVersion
|
2014-05-29 09:17:39 +01:00
|
|
|
new ResponseEntity<byte[]>(render('starter-pom.xml', request, model), ['Content-Type':'application/octet-stream'] as HttpHeaders, HttpStatus.OK)
|
2014-01-21 15:34:41 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
@RequestMapping('/build')
|
2014-01-21 15:34:41 +00:00
|
|
|
@ResponseBody
|
|
|
|
ResponseEntity<byte[]> gradle(PomRequest request, Map model) {
|
2014-04-01 17:22:18 +01:00
|
|
|
model.bootVersion = bootVersion
|
2014-05-29 09:17:39 +01:00
|
|
|
new ResponseEntity<byte[]>(render('starter-build.gradle', request, model), ['Content-Type':'application/octet-stream'] as HttpHeaders, HttpStatus.OK)
|
2014-01-21 15:34:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
byte[] render(String path, PomRequest request, Map model) {
|
2013-06-06 08:40:10 +01:00
|
|
|
|
2014-05-29 16:26:47 +01:00
|
|
|
if (request.packaging=='war' && !request.style.any { isWebStyle(it) }) {
|
|
|
|
request.style << 'web'
|
|
|
|
}
|
|
|
|
|
2013-06-06 08:40:10 +01:00
|
|
|
def style = request.style
|
2014-05-29 09:17:39 +01:00
|
|
|
log.info('Styles requested: ' + style)
|
2013-06-06 08:40:10 +01:00
|
|
|
|
2013-11-01 14:39:56 +00:00
|
|
|
def type = request.type
|
2014-05-29 09:17:39 +01:00
|
|
|
log.info('Type requested: ' + type)
|
2013-11-01 14:39:56 +00:00
|
|
|
|
2013-06-06 08:40:10 +01:00
|
|
|
model.groupId = request.groupId
|
|
|
|
model.artifactId = request.artifactId
|
|
|
|
model.version = request.version
|
|
|
|
model.name = request.name
|
|
|
|
model.description = request.description
|
|
|
|
model.packageName = request.packageName
|
2014-05-29 16:26:47 +01:00
|
|
|
model.packaging = request.packaging
|
2014-05-30 06:18:33 +01:00
|
|
|
model.javaVersion = request.javaVersion
|
2014-05-30 09:50:24 +01:00
|
|
|
model.language = request.language
|
2013-06-06 08:40:10 +01:00
|
|
|
|
|
|
|
if (style==null || style.size()==0) {
|
2014-05-29 09:17:39 +01:00
|
|
|
style = ['']
|
2013-06-06 08:40:10 +01:00
|
|
|
}
|
2013-08-19 17:21:45 +01:00
|
|
|
if (!style.class.isArray() && !(style instanceof Collection)) {
|
|
|
|
style = [style]
|
|
|
|
}
|
2014-05-29 09:17:39 +01:00
|
|
|
style = style.collect{ it=='jpa' ? 'data-jpa' : it }
|
|
|
|
model['styles'] = style.collect{ it=='' ? '' : '-' + it }
|
2013-06-06 08:40:10 +01:00
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
log.info('Model: ' + model)
|
2013-06-06 08:40:10 +01:00
|
|
|
|
2014-01-21 15:34:41 +00:00
|
|
|
def body = template path, model
|
|
|
|
body
|
2013-06-06 08:40:10 +01:00
|
|
|
}
|
|
|
|
|
2014-05-29 16:26:47 +01:00
|
|
|
private boolean isWebStyle(String style) {
|
|
|
|
return style.contains('web') || style.contains('thymeleaf') || style.contains('freemarker') || style.contains('velocity') || style.contains('groovy-template')
|
|
|
|
}
|
|
|
|
|
2013-06-06 12:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-05-28 17:26:53 +01:00
|
|
|
@EnableReactor
|
2014-05-28 19:25:35 +01:00
|
|
|
@Consumer
|
2013-08-04 13:50:06 +01:00
|
|
|
@Log
|
|
|
|
class TemporaryFileCleaner {
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
Reactor reactor
|
|
|
|
|
2014-05-28 19:25:35 +01:00
|
|
|
@Selector('tempfiles')
|
|
|
|
void clean(def tempFiles) {
|
2014-05-29 16:26:47 +01:00
|
|
|
log.fine 'Tempfiles: ' + tempFiles
|
2014-05-28 19:25:35 +01:00
|
|
|
if (tempFiles) {
|
|
|
|
tempFiles.each {
|
|
|
|
File file = it as File
|
|
|
|
if (file.directory) {
|
|
|
|
file.deleteDir()
|
|
|
|
} else {
|
|
|
|
file.delete()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-08-04 13:50:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-06-06 08:40:10 +01:00
|
|
|
class PomRequest {
|
|
|
|
def style = []
|
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
String name = 'demo'
|
|
|
|
String type = 'starter'
|
|
|
|
String description = 'Demo project for Spring Boot'
|
|
|
|
String groupId = 'org.test'
|
2013-06-06 08:40:10 +01:00
|
|
|
String artifactId
|
2014-05-29 09:17:39 +01:00
|
|
|
String version = '0.0.1-SNAPSHOT'
|
2014-05-29 16:26:47 +01:00
|
|
|
String packaging = 'jar'
|
2014-05-30 09:50:24 +01:00
|
|
|
String language = 'java'
|
2013-06-06 08:40:10 +01:00
|
|
|
String packageName
|
2014-05-30 06:18:33 +01:00
|
|
|
String javaVersion = '1.7'
|
2013-08-04 13:50:06 +01:00
|
|
|
String getArtifactId() {
|
2013-06-06 08:40:10 +01:00
|
|
|
artifactId == null ? name : artifactId
|
|
|
|
}
|
|
|
|
String getPackageName() {
|
2013-08-16 17:39:01 +01:00
|
|
|
packageName == null ? name.replace('-', '.') : packageName
|
2013-06-06 08:40:10 +01:00
|
|
|
}
|
2013-08-16 17:39:01 +01:00
|
|
|
}
|
2014-05-28 19:25:35 +01:00
|
|
|
|
2014-05-29 09:17:39 +01:00
|
|
|
@Component
|
2014-05-28 19:25:35 +01:00
|
|
|
@ConfigurationProperties(prefix='projects', ignoreUnknownFields=false)
|
|
|
|
class Projects {
|
|
|
|
List<Map<String,Object>> styles
|
2014-05-29 16:26:47 +01:00
|
|
|
List<Type> types
|
|
|
|
List<Packaging> packagings
|
2014-05-30 06:18:33 +01:00
|
|
|
List<JavaVersion> javaVersions
|
2014-05-30 09:50:24 +01:00
|
|
|
List<Language> languages
|
|
|
|
static class Language {
|
|
|
|
String name
|
|
|
|
String value
|
|
|
|
boolean selected
|
|
|
|
}
|
2014-05-30 06:18:33 +01:00
|
|
|
static class JavaVersion {
|
|
|
|
String value
|
|
|
|
boolean selected
|
|
|
|
}
|
2014-05-29 16:26:47 +01:00
|
|
|
static class Packaging {
|
|
|
|
String name
|
|
|
|
String value
|
|
|
|
boolean selected
|
|
|
|
}
|
|
|
|
static class Type {
|
|
|
|
String name
|
|
|
|
String action
|
|
|
|
String value
|
|
|
|
boolean selected
|
|
|
|
}
|
2014-05-28 19:25:35 +01:00
|
|
|
}
|