Add sample project for Groovy templates
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.ui;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class InMemoryMessageRespository implements MessageRepository {
|
||||
|
||||
private static AtomicLong counter = new AtomicLong();
|
||||
|
||||
private final ConcurrentMap<Long, Message> messages = new ConcurrentHashMap<Long, Message>();
|
||||
|
||||
@Override
|
||||
public Iterable<Message> findAll() {
|
||||
return this.messages.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message save(Message message) {
|
||||
Long id = message.getId();
|
||||
if (id == null) {
|
||||
id = counter.incrementAndGet();
|
||||
message.setId(id);
|
||||
}
|
||||
this.messages.put(id, message);
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message findMessage(Long id) {
|
||||
return this.messages.get(id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.ui;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class Message {
|
||||
|
||||
private Long id;
|
||||
|
||||
@NotEmpty(message = "Message is required.")
|
||||
private String text;
|
||||
|
||||
@NotEmpty(message = "Summary is required.")
|
||||
private String summary;
|
||||
|
||||
private Date created = new Date();
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return this.created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getSummary() {
|
||||
return this.summary;
|
||||
}
|
||||
|
||||
public void setSummary(String summary) {
|
||||
this.summary = summary;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.ui;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public interface MessageRepository {
|
||||
|
||||
Iterable<Message> findAll();
|
||||
|
||||
Message save(Message message);
|
||||
|
||||
Message findMessage(Long id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.ui;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan
|
||||
public class SampleGroovyTemplateApplication {
|
||||
|
||||
@Bean
|
||||
public MessageRepository messageRepository() {
|
||||
return new InMemoryMessageRespository();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Converter<String, Message> messageConverter() {
|
||||
return new Converter<String, Message>() {
|
||||
@Override
|
||||
public Message convert(String id) {
|
||||
return messageRepository().findMessage(Long.valueOf(id));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(SampleGroovyTemplateApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.ui.mvc;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import sample.ui.Message;
|
||||
import sample.ui.MessageRepository;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/")
|
||||
public class MessageController {
|
||||
private final MessageRepository messageRepository;
|
||||
|
||||
@Autowired
|
||||
public MessageController(MessageRepository messageRepository) {
|
||||
this.messageRepository = messageRepository;
|
||||
}
|
||||
|
||||
@RequestMapping
|
||||
public ModelAndView list() {
|
||||
Iterable<Message> messages = this.messageRepository.findAll();
|
||||
return new ModelAndView("messages/list", "messages", messages);
|
||||
}
|
||||
|
||||
@RequestMapping("{id}")
|
||||
public ModelAndView view(@PathVariable("id") Message message) {
|
||||
return new ModelAndView("messages/view", "message", message);
|
||||
}
|
||||
|
||||
@RequestMapping(params = "form", method = RequestMethod.GET)
|
||||
public String createForm(@ModelAttribute Message message) {
|
||||
return "messages/form";
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public ModelAndView create(@Valid Message message, BindingResult result,
|
||||
RedirectAttributes redirect) {
|
||||
if (result.hasErrors()) {
|
||||
ModelAndView mav = new ModelAndView("messages/form");
|
||||
mav.addObject("formErrors", result.getAllErrors());
|
||||
mav.addObject("fieldErrors", getFieldErrors(result));
|
||||
return mav;
|
||||
}
|
||||
message = this.messageRepository.save(message);
|
||||
redirect.addFlashAttribute("globalMessage", "Successfully created a new message");
|
||||
return new ModelAndView("redirect:/{message.id}", "message.id", message.getId());
|
||||
}
|
||||
|
||||
private Map<String, ObjectError> getFieldErrors(BindingResult result) {
|
||||
Map<String, ObjectError> map = new HashMap<String, ObjectError>();
|
||||
for (FieldError error : result.getFieldErrors()) {
|
||||
map.put(error.getField(), error);
|
||||
}
|
||||
return map ;
|
||||
}
|
||||
|
||||
@RequestMapping("foo")
|
||||
public String foo() {
|
||||
throw new RuntimeException("Expected exception in controller");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# Allow templates to be reloaded at dev time
|
||||
spring.groovy.template.cache: false
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||
|
||||
<logger name="org.springframework.web" level="DEBUG"/>
|
||||
|
||||
</configuration>
|
||||
File diff suppressed because one or more lines are too long
9404
spring-boot-samples/spring-boot-sample-web-groovy-templates/src/main/resources/static/js/jquery-1.7.2.js
vendored
Normal file
9404
spring-boot-samples/spring-boot-sample-web-groovy-templates/src/main/resources/static/js/jquery-1.7.2.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
html {
|
||||
head {
|
||||
title(title)
|
||||
link(rel:'stylesheet', href:'/css/bootstrap.min.css')
|
||||
}
|
||||
body {
|
||||
div(class:'container') {
|
||||
div(class:'navbar') {
|
||||
div(class:'navbar-inner') {
|
||||
a(class:'brand',
|
||||
href:'http://beta.groovy-lang.org/docs/groovy-2.3.0/html/documentation/markup-template-engine.html') {
|
||||
yield 'Groovy - Layout'
|
||||
}
|
||||
ul(class:'nav') {
|
||||
li {
|
||||
a(href:'/') {
|
||||
yield 'Messages'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
h1(title)
|
||||
div { content() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
layout 'layout.tpl', title: 'Messages : Create',
|
||||
content: contents {
|
||||
div (class:'container') {
|
||||
form (id:'messageForm', action:'/', method:'post') {
|
||||
if (formErrors) {
|
||||
div(class:'alert alert-error') {
|
||||
formErrors.each { error ->
|
||||
p error.defaultMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
div (class:'pull-right') {
|
||||
a (href:'/', 'Messages')
|
||||
}
|
||||
label (for:'summary', 'Summary')
|
||||
input (name:'summary', type:'text', value:message.summary?:'',
|
||||
class:fieldErrors?.summary ? 'field-error' : 'none')
|
||||
label (for:'text', 'Message')
|
||||
textarea (name:'text', class:fieldErrors?.text ? 'field-error' : 'none', message.text?:'')
|
||||
div (class:'form-actions') {
|
||||
input (type:'submit', value:'Create')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
layout 'layout.tpl', title: 'Messages : View all',
|
||||
content: contents {
|
||||
div(class:'container') {
|
||||
div(class:'pull-right') {
|
||||
a(href:'/?form', 'Create Message')
|
||||
}
|
||||
table(class:'table table-bordered table-striped') {
|
||||
thead {
|
||||
tr {
|
||||
td 'ID'
|
||||
td 'Created'
|
||||
td 'Summary'
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
if (messages.empty) { tr { td(colspan:'3', 'No Messages' ) } }
|
||||
messages.each { message ->
|
||||
tr {
|
||||
td message.id
|
||||
td "${message.created}"
|
||||
td {
|
||||
a(href:"/${message.id}") {
|
||||
yield message.getSummary()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
layout 'layout.tpl', title:'Messages : View',
|
||||
content: contents {
|
||||
div(class:'container') {
|
||||
if (globalMessage) {
|
||||
div (class:'alert alert-success', globalMessage)
|
||||
}
|
||||
div(class:'pull-right') {
|
||||
a(href:'/', 'Messages')
|
||||
}
|
||||
dl {
|
||||
dt 'ID'
|
||||
dd(id:'id', message.id)
|
||||
dt 'Date'
|
||||
dd(id:'created', "${message.created}")
|
||||
dt 'Summary'
|
||||
dd(id:'summary', message.summary)
|
||||
dt 'Message'
|
||||
dd(id:'text', message.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user