├── src ├── main │ ├── webapp │ │ ├── META-INF │ │ │ └── MANIFEST.MF │ │ ├── WEB-INF │ │ │ ├── templates │ │ │ │ ├── product │ │ │ │ │ ├── list.properties │ │ │ │ │ ├── comments.html │ │ │ │ │ └── list.html │ │ │ │ ├── subscribe.properties │ │ │ │ ├── subscribe_es.properties │ │ │ │ ├── home_nl.properties │ │ │ │ ├── home_fr.properties │ │ │ │ ├── home_en.properties │ │ │ │ ├── home_pt.properties │ │ │ │ ├── home.properties │ │ │ │ ├── home_gl.properties │ │ │ │ ├── home_de.properties │ │ │ │ ├── home_es.properties │ │ │ │ ├── footer.html │ │ │ │ ├── subscribe.html │ │ │ │ ├── userprofile.html │ │ │ │ ├── order │ │ │ │ │ ├── list.html │ │ │ │ │ └── details.html │ │ │ │ └── home.html │ │ │ └── web.xml │ │ ├── images │ │ │ └── gtvglogo.png │ │ └── css │ │ │ └── gtvg.css │ ├── resources │ │ └── log4j.properties │ └── java │ │ └── thymeleafexamples │ │ └── gtvg │ │ ├── web │ │ ├── controller │ │ │ ├── IGTVGController.java │ │ │ ├── SubscribeController.java │ │ │ ├── UserProfileController.java │ │ │ ├── HomeController.java │ │ │ ├── OrderListController.java │ │ │ ├── ProductListController.java │ │ │ ├── OrderDetailsController.java │ │ │ └── ProductCommentsController.java │ │ ├── mapping │ │ │ └── ControllerMappings.java │ │ └── filter │ │ │ └── GTVGFilter.java │ │ └── business │ │ ├── services │ │ ├── ProductService.java │ │ ├── CustomerService.java │ │ └── OrderService.java │ │ ├── entities │ │ ├── Comment.java │ │ ├── Customer.java │ │ ├── OrderLine.java │ │ ├── User.java │ │ ├── Order.java │ │ ├── Product.java │ │ └── repositories │ │ │ ├── CustomerRepository.java │ │ │ ├── OrderRepository.java │ │ │ └── ProductRepository.java │ │ └── util │ │ └── CalendarUtil.java └── assembly │ └── sources.xml ├── .gitignore ├── README.markdown ├── NOTICE.txt ├── CONTRIBUTING.markdown ├── pom.xml └── LICENSE.txt /src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | 3 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/product/list.properties: -------------------------------------------------------------------------------- 1 | true=yes 2 | false=no -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/subscribe.properties: -------------------------------------------------------------------------------- 1 | subscribe.submit=Subscribe me! -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/subscribe_es.properties: -------------------------------------------------------------------------------- 1 | subscribe.submit=\u00A1Suscr\u00EDbeme! -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | target/ 4 | bin/ 5 | .settings/ 6 | .idea/ 7 | *.iml 8 | 9 | -------------------------------------------------------------------------------- /src/main/webapp/images/gtvglogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleafexamples-gtvg/HEAD/src/main/webapp/images/gtvglogo.png -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home_nl.properties: -------------------------------------------------------------------------------- 1 | home.welcome=Welkom op onze kruidenier, {0}! 2 | logo=Logo Good Thymes Virtual Grocery 3 | date.format=dd MMMM'','' yyyy -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home_fr.properties: -------------------------------------------------------------------------------- 1 | home.welcome=Bienvenue \u00E0 notre \u00E9picerie, {0}! 2 | logo=Logo Good Thymes Virtual Grocery 3 | date.format=dd MMMM'','' yyyy -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home_en.properties: -------------------------------------------------------------------------------- 1 | home.welcome=Welcome to our fantastic grocery store, {0}! 2 | logo=Good Thymes Virtual Grocery logo 3 | date.format=MMMM dd'','' yyyy -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home_pt.properties: -------------------------------------------------------------------------------- 1 | home.welcome=Bem-vindo \u00E1 nossa mercearia, {0}! 2 | logo=Logo da Good Thymes Virtual Grocery 3 | date.format=dd ''de'' MMMM'','' yyyy -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home.properties: -------------------------------------------------------------------------------- 1 | home.welcome=Welcome to our grocery store, {0} (from default messages)! 2 | logo=Good Thymes Virtual Grocery logo 3 | date.format=MMMM dd'','' yyyy -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home_gl.properties: -------------------------------------------------------------------------------- 1 | home.welcome=Benvido \u00E1 nosa tenda de comestibles, {0}! 2 | logo=Logo de Good Thymes Virtual Grocery 3 | date.format=dd ''de'' MMMM'','' yyyy -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home_de.properties: -------------------------------------------------------------------------------- 1 | home.welcome=Herzlich Willkommen auf unserer Lebensmittelgesch\u00E4ft, {0}! 2 | logo=Logo Good Thymes Virtual Grocery 3 | date.format=dd MMMM'','' yyyy -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home_es.properties: -------------------------------------------------------------------------------- 1 | home.welcome=\u00A1Bienvenido a nuestra tienda de comestibles, {0}! 2 | logo=Logo de Good Thymes Virtual Grocery 3 | date.format=dd ''de'' MMMM'','' yyyy -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | © 2011 The Good Thymes Virtual Grocery 9 |
10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | 2 | Thymeleaf Examples: Good Thymes Virtual Grocery 3 | ----------------------------------------------- 4 | 5 | This is an example project containing code used in the "Using Thymeleaf" tutorial. 6 | 7 | To learn more: 8 | 9 | http://www.thymeleaf.org 10 | 11 | 12 | Building 13 | -------- 14 | 15 | To build this project you will need Maven 2. You can get it at: 16 | 17 | http://maven.apache.org 18 | 19 | Clean compilation products: 20 | 21 | mvn clean 22 | 23 | Compile: 24 | 25 | mvn compile 26 | 27 | Create a war package: 28 | 29 | mvn package 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2013, The THYMELEAF team (http://www.thymeleaf.org) 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 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger = WARN, stdout 2 | 3 | log4j.appender.stdout = org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout = org.apache.log4j.PatternLayout 5 | log4j.appender.stdout.layout.ConversionPattern=%d %5p [%c{1}] (%F:%L) - %m%n 6 | 7 | log4j.logger.org.thymeleaf=DEBUG 8 | log4j.logger.org.thymeleaf.TemplateEngine=DEBUG 9 | log4j.logger.org.thymeleaf.TemplateEngine.CONFIG=DEBUG 10 | log4j.logger.org.thymeleaf.TemplateEngine.TIMER=DEBUG 11 | log4j.logger.org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE=DEBUG 12 | log4j.logger.org.thymeleaf.TemplateEngine.cache.FRAGMENT_CACHE=DEBUG 13 | log4j.logger.org.thymeleaf.TemplateEngine.cache.MESSAGE_CACHE=DEBUG 14 | log4j.logger.org.thymeleaf.TemplateEngine.cache.EXPRESSION_CACHE=DEBUG 15 | log4j.logger.thymeleafexamples=DEBUG -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/subscribe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Good Thymes Virtual Grocery 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Subscribe to our newsletter:

14 | 15 |
16 |
17 | 18 | 19 |
20 |
21 | 22 |

23 | Return to home 24 |

25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/product/comments.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Good Thymes Virtual Grocery 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Comments for product: Hot Garlic

14 | 15 | 16 | 17 | 18 | 19 |
Garlic is just fantastic!
20 | 21 |

22 | Return to product list 23 |

24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | thymeleafexamples-gtvg 10 | 11 | 12 | 60 13 | 14 | 15 | 16 | gtvgfilter 17 | thymeleafexamples.gtvg.web.filter.GTVGFilter 18 | 19 | 20 | 21 | 22 | gtvgfilter 23 | /* 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/userprofile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Good Thymes Virtual Grocery 7 | 8 | 9 | 10 | 11 | 12 | 13 |

User profile

14 | 15 |
16 |

Name: Sebastian.

17 |

Surname: Pepper.

18 |

Nationality: Saturn.

19 |

Age: 27.

20 |
21 | 22 |

23 | Return to home 24 |

25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/assembly/sources.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sources 7 | 8 | 9 | zip 10 | 11 | 12 | 13 | 14 | ${basedir}/src/ 15 | /src/ 16 | 17 | **/* 18 | 19 | 20 | 21 | ${basedir}/ 22 | / 23 | 24 | CONTRIBUTING.markdown 25 | LICENSE.txt 26 | README.txt 27 | BUILD.txt 28 | NOTICE.txt 29 | pom.xml 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/order/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Good Thymes Virtual Grocery 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Order list

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 |
DATECUSTOMERTOTAL
13 jan 2011Frederic Tomato23.32 27 | view 28 |
31 | 32 | 33 |

34 | Return to home 35 |

36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/controller/IGTVGController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.controller; 21 | 22 | import java.io.Writer; 23 | 24 | import org.thymeleaf.ITemplateEngine; 25 | import org.thymeleaf.web.IWebExchange; 26 | 27 | public interface IGTVGController { 28 | 29 | 30 | public void process(final IWebExchange webExchange, final ITemplateEngine templateEngine, final Writer writer) 31 | throws Exception; 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Good Thymes Virtual Grocery 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | GTVG logo 16 |
17 | 18 |

Welcome to our grocery store, Sebastian!

19 | 20 |

21 | Today is: 13 February 2011 22 |

23 | 24 |

Please select an option

25 |
    26 |
  1. Product List
  2. 27 |
  3. Order List
  4. 28 |
  5. Subscribe to our Newsletter
  6. 29 |
  7. See User Profile
  8. 30 |
31 | 32 |

Now you are looking at a template file.

33 | 34 |
© 2011 The Static Templates
35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/main/webapp/css/gtvg.css: -------------------------------------------------------------------------------- 1 | 2 | html { 3 | background-color: #f0f0f0; 4 | } 5 | 6 | body { 7 | font-family: 'DejaVu Sans', Arial, Helvetica; 8 | font-size: 12px; 9 | background-color: #ffffff; 10 | border: 1px solid #cccccc; 11 | margin: 0px auto; 12 | padding: 20px 20px; 13 | width: 850px; 14 | } 15 | 16 | h2 { 17 | margin-top: 50px; 18 | margin-bottom: 30px; 19 | } 20 | 21 | 22 | tr.odd td { 23 | background-color: #f0faaa; 24 | } 25 | 26 | td.number { 27 | text-align: right; 28 | } 29 | 30 | 31 | table { 32 | width: 100%; 33 | border: 1px solid #000; 34 | border-collapse: collapse; 35 | } 36 | 37 | table > tbody > tr > td, table > thead > tr > th { 38 | padding: 2px 10px; 39 | border-left: 1px dotted #000000; 40 | vertical-align: top; 41 | line-height: 20px; 42 | } 43 | 44 | table > tbody > tr, table > thead > tr { 45 | border-bottom: 1px solid #000000; 46 | } 47 | 48 | table th { 49 | background-color: #99cc33; 50 | } 51 | 52 | table > tbody > tr > td > a, table > tbody > tr > td > a:hover { 53 | text-decoration: none; 54 | font-weight: bold; 55 | background-color: #352726; 56 | padding: 2px 10px; 57 | color: #f0faaa; 58 | margin-left: 10px; 59 | text-transform: uppercase; 60 | border: 0px; 61 | } 62 | 63 | 64 | ol > li { 65 | margin-top: 10px; 66 | } 67 | 68 | a { 69 | text-decoration: none; 70 | color: #777; 71 | border-bottom: 1px dotted #777; 72 | } 73 | 74 | a:hover { 75 | color: #99cc33; 76 | border-bottom: 1px solid #99cc33; 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/services/ProductService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.services; 21 | 22 | import java.util.List; 23 | 24 | import thymeleafexamples.gtvg.business.entities.Product; 25 | import thymeleafexamples.gtvg.business.entities.repositories.ProductRepository; 26 | 27 | public class ProductService { 28 | 29 | 30 | 31 | public ProductService() { 32 | super(); 33 | } 34 | 35 | 36 | 37 | public List findAll() { 38 | return ProductRepository.getInstance().findAll(); 39 | } 40 | 41 | public Product findById(final Integer id) { 42 | return ProductRepository.getInstance().findById(id); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/services/CustomerService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.services; 21 | 22 | import java.util.List; 23 | 24 | import thymeleafexamples.gtvg.business.entities.Customer; 25 | import thymeleafexamples.gtvg.business.entities.repositories.CustomerRepository; 26 | 27 | public class CustomerService { 28 | 29 | 30 | 31 | public CustomerService() { 32 | super(); 33 | } 34 | 35 | 36 | 37 | public List findAll() { 38 | return CustomerRepository.getInstance().findAll(); 39 | } 40 | 41 | public Customer findById(final Integer id) { 42 | return CustomerRepository.getInstance().findById(id); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/Comment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities; 21 | 22 | 23 | public class Comment { 24 | 25 | private Integer id = null; 26 | private String text = null; 27 | 28 | 29 | public Comment() { 30 | super(); 31 | } 32 | 33 | public Comment(final Integer id, final String text) { 34 | this.id = id; 35 | this.text = text; 36 | } 37 | 38 | public Integer getId() { 39 | return this.id; 40 | } 41 | public void setId(final Integer id) { 42 | this.id = id; 43 | } 44 | 45 | 46 | public String getText() { 47 | return this.text; 48 | } 49 | public void setText(final String text) { 50 | this.text = text; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/controller/SubscribeController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.controller; 21 | 22 | import java.io.Writer; 23 | 24 | import org.thymeleaf.ITemplateEngine; 25 | import org.thymeleaf.context.WebContext; 26 | import org.thymeleaf.web.IWebExchange; 27 | 28 | public class SubscribeController implements IGTVGController { 29 | 30 | 31 | public SubscribeController() { 32 | super(); 33 | } 34 | 35 | 36 | public void process(final IWebExchange webExchange, final ITemplateEngine templateEngine, final Writer writer) 37 | throws Exception { 38 | 39 | WebContext ctx = new WebContext(webExchange, webExchange.getLocale()); 40 | templateEngine.process("subscribe", ctx, writer); 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/controller/UserProfileController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.controller; 21 | 22 | import java.io.Writer; 23 | 24 | import org.thymeleaf.ITemplateEngine; 25 | import org.thymeleaf.context.WebContext; 26 | import org.thymeleaf.web.IWebExchange; 27 | 28 | public class UserProfileController implements IGTVGController { 29 | 30 | 31 | public UserProfileController() { 32 | super(); 33 | } 34 | 35 | 36 | public void process(final IWebExchange webExchange, final ITemplateEngine templateEngine, final Writer writer) 37 | throws Exception { 38 | 39 | final WebContext ctx = new WebContext(webExchange, webExchange.getLocale()); 40 | templateEngine.process("userprofile", ctx, writer); 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/order/details.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Good Thymes Virtual Grocery 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Order details

14 | 15 |
16 |

Code: 99

17 |

Date: 13 jan 2011

18 |
19 | 20 |

Customer

21 | 22 |
23 |

Name: Frederic Tomato

24 |

Since: 13 jan 2011

25 |
26 | 27 |

Products

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
PRODUCTAMOUNTPURCHASE PRICE
Strawberries323.32
41 | 42 |
43 | TOTAL: 35.23 44 |
45 | 46 |

47 | Return to order list 48 |

49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/services/OrderService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.services; 21 | 22 | import java.util.List; 23 | 24 | import thymeleafexamples.gtvg.business.entities.Order; 25 | import thymeleafexamples.gtvg.business.entities.repositories.OrderRepository; 26 | 27 | public class OrderService { 28 | 29 | 30 | 31 | public OrderService() { 32 | super(); 33 | } 34 | 35 | 36 | 37 | public List findAll() { 38 | return OrderRepository.getInstance().findAll(); 39 | } 40 | 41 | public Order findById(final Integer id) { 42 | return OrderRepository.getInstance().findById(id); 43 | } 44 | 45 | public List findByCustomerId(final Integer customerId) { 46 | return OrderRepository.getInstance().findByCustomerId(customerId); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/controller/HomeController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.controller; 21 | 22 | import java.io.Writer; 23 | import java.util.Calendar; 24 | 25 | import org.thymeleaf.ITemplateEngine; 26 | import org.thymeleaf.context.WebContext; 27 | import org.thymeleaf.web.IWebExchange; 28 | 29 | public class HomeController implements IGTVGController { 30 | 31 | 32 | public HomeController() { 33 | super(); 34 | } 35 | 36 | 37 | public void process(final IWebExchange webExchange, final ITemplateEngine templateEngine, final Writer writer) 38 | throws Exception { 39 | 40 | WebContext ctx = new WebContext(webExchange, webExchange.getLocale()); 41 | ctx.setVariable("today", Calendar.getInstance()); 42 | 43 | templateEngine.process("home", ctx, writer); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/util/CalendarUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.util; 21 | 22 | import java.util.Calendar; 23 | 24 | 25 | 26 | public class CalendarUtil { 27 | 28 | 29 | public static Calendar calendarFor( 30 | final int year, final int month, final int day, final int hour, final int minute) { 31 | 32 | final Calendar cal = Calendar.getInstance(); 33 | cal.set(Calendar.YEAR, year); 34 | cal.set(Calendar.MONTH, month - 1); 35 | cal.set(Calendar.DAY_OF_MONTH, day); 36 | cal.set(Calendar.HOUR_OF_DAY, hour); 37 | cal.set(Calendar.MINUTE, minute); 38 | cal.set(Calendar.SECOND, 0); 39 | cal.set(Calendar.MILLISECOND, 0); 40 | return cal; 41 | 42 | } 43 | 44 | 45 | 46 | private CalendarUtil() { 47 | super(); 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/Customer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities; 21 | 22 | import java.util.Calendar; 23 | 24 | public class Customer { 25 | 26 | private Integer id = null; 27 | private String name = null; 28 | private Calendar customerSince = null; 29 | 30 | 31 | public Customer() { 32 | super(); 33 | } 34 | 35 | 36 | public Integer getId() { 37 | return this.id; 38 | } 39 | public void setId(final Integer id) { 40 | this.id = id; 41 | } 42 | 43 | 44 | public String getName() { 45 | return this.name; 46 | } 47 | public void setName(final String name) { 48 | this.name = name; 49 | } 50 | 51 | 52 | public Calendar getCustomerSince() { 53 | return this.customerSince; 54 | } 55 | public void setCustomerSince(final Calendar customerSince) { 56 | this.customerSince = customerSince; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/OrderLine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities; 21 | 22 | import java.math.BigDecimal; 23 | 24 | public class OrderLine { 25 | 26 | private Product product = null; 27 | private Integer amount = null; 28 | private BigDecimal purchasePrice = null; 29 | 30 | 31 | public OrderLine() { 32 | super(); 33 | } 34 | 35 | 36 | public Product getProduct() { 37 | return this.product; 38 | } 39 | public void setProduct(final Product product) { 40 | this.product = product; 41 | } 42 | 43 | 44 | public Integer getAmount() { 45 | return this.amount; 46 | } 47 | public void setAmount(final Integer amount) { 48 | this.amount = amount; 49 | } 50 | 51 | 52 | public BigDecimal getPurchasePrice() { 53 | return this.purchasePrice; 54 | } 55 | public void setPurchasePrice(final BigDecimal purchasePrice) { 56 | this.purchasePrice = purchasePrice; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/product/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Good Thymes Virtual Grocery 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Product list

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 |
NAMEPRICEIN STOCKCOMMENTS
Onions2.41yes 30 | 2 comment/s 31 | view 34 |
Blue Lettuce9.55no 41 | 0 comment/s 42 |
Mild Cinnamon1.99yes 49 | 3 comment/s 50 | view 51 |
55 | 56 |

57 | Return to home 58 |

59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities; 21 | 22 | 23 | public class User { 24 | 25 | private String firstName = null; 26 | private String lastName = null; 27 | private String nationality = null; 28 | private Integer age = null; 29 | 30 | 31 | public User(final String firstName, final String lastName, 32 | final String nationality, final Integer age) { 33 | super(); 34 | this.firstName = firstName; 35 | this.lastName = lastName; 36 | this.nationality = nationality; 37 | this.age = age; 38 | } 39 | 40 | 41 | public String getFirstName() { 42 | return this.firstName; 43 | } 44 | 45 | public String getLastName() { 46 | return this.lastName; 47 | } 48 | 49 | public String getName() { 50 | return this.firstName + " " + this.lastName; 51 | } 52 | 53 | public String getNationality() { 54 | return this.nationality; 55 | } 56 | 57 | public Integer getAge() { 58 | return this.age; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/controller/OrderListController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.controller; 21 | 22 | import java.io.Writer; 23 | import java.util.List; 24 | 25 | import org.thymeleaf.ITemplateEngine; 26 | import org.thymeleaf.context.WebContext; 27 | import org.thymeleaf.web.IWebExchange; 28 | import thymeleafexamples.gtvg.business.entities.Order; 29 | import thymeleafexamples.gtvg.business.services.OrderService; 30 | 31 | public class OrderListController implements IGTVGController { 32 | 33 | 34 | public OrderListController() { 35 | super(); 36 | } 37 | 38 | 39 | public void process(final IWebExchange webExchange, final ITemplateEngine templateEngine, final Writer writer) 40 | throws Exception { 41 | 42 | final OrderService orderService = new OrderService(); 43 | final List allOrders = orderService.findAll(); 44 | 45 | final WebContext ctx = new WebContext(webExchange, webExchange.getLocale()); 46 | ctx.setVariable("orders", allOrders); 47 | 48 | templateEngine.process("order/list", ctx, writer); 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/Order.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities; 21 | 22 | import java.util.Calendar; 23 | import java.util.LinkedHashSet; 24 | import java.util.Set; 25 | 26 | public class Order { 27 | 28 | private Integer id = null; 29 | private Calendar date = null; 30 | private Customer customer = null; 31 | private Set orderLines = new LinkedHashSet(); 32 | 33 | public Order() { 34 | super(); 35 | } 36 | 37 | 38 | public Integer getId() { 39 | return this.id; 40 | } 41 | public void setId(final Integer id) { 42 | this.id = id; 43 | } 44 | 45 | 46 | public Calendar getDate() { 47 | return this.date; 48 | } 49 | public void setDate(final Calendar date) { 50 | this.date = date; 51 | } 52 | 53 | 54 | public Customer getCustomer() { 55 | return this.customer; 56 | } 57 | public void setCustomer(final Customer customer) { 58 | this.customer = customer; 59 | } 60 | 61 | 62 | public Set getOrderLines() { 63 | return this.orderLines; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/controller/ProductListController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.controller; 21 | 22 | import java.io.Writer; 23 | import java.util.List; 24 | 25 | import org.thymeleaf.ITemplateEngine; 26 | import org.thymeleaf.context.WebContext; 27 | import org.thymeleaf.web.IWebExchange; 28 | import thymeleafexamples.gtvg.business.entities.Product; 29 | import thymeleafexamples.gtvg.business.services.ProductService; 30 | 31 | public class ProductListController implements IGTVGController { 32 | 33 | 34 | public ProductListController() { 35 | super(); 36 | } 37 | 38 | 39 | public void process(final IWebExchange webExchange, final ITemplateEngine templateEngine, final Writer writer) 40 | throws Exception { 41 | 42 | final ProductService productService = new ProductService(); 43 | final List allProducts = productService.findAll(); 44 | 45 | final WebContext ctx = new WebContext(webExchange, webExchange.getLocale()); 46 | ctx.setVariable("prods", allProducts); 47 | 48 | templateEngine.process("product/list", ctx, writer); 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/controller/OrderDetailsController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.controller; 21 | 22 | import java.io.Writer; 23 | 24 | import org.thymeleaf.ITemplateEngine; 25 | import org.thymeleaf.context.WebContext; 26 | import org.thymeleaf.web.IWebExchange; 27 | import thymeleafexamples.gtvg.business.entities.Order; 28 | import thymeleafexamples.gtvg.business.services.OrderService; 29 | 30 | public class OrderDetailsController implements IGTVGController { 31 | 32 | 33 | public OrderDetailsController() { 34 | super(); 35 | } 36 | 37 | 38 | public void process(final IWebExchange webExchange, final ITemplateEngine templateEngine, final Writer writer) 39 | throws Exception { 40 | 41 | final Integer orderId = Integer.valueOf(webExchange.getRequest().getParameterValue("orderId")); 42 | 43 | final OrderService orderService = new OrderService(); 44 | final Order order = orderService.findById(orderId); 45 | 46 | final WebContext ctx = new WebContext(webExchange, webExchange.getLocale()); 47 | ctx.setVariable("order", order); 48 | 49 | templateEngine.process("order/details", ctx, writer); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/controller/ProductCommentsController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.controller; 21 | 22 | import java.io.Writer; 23 | 24 | import org.thymeleaf.ITemplateEngine; 25 | import org.thymeleaf.context.WebContext; 26 | import org.thymeleaf.web.IWebExchange; 27 | import thymeleafexamples.gtvg.business.entities.Product; 28 | import thymeleafexamples.gtvg.business.services.ProductService; 29 | 30 | public class ProductCommentsController implements IGTVGController { 31 | 32 | 33 | public ProductCommentsController() { 34 | super(); 35 | } 36 | 37 | 38 | public void process(final IWebExchange webExchange, final ITemplateEngine templateEngine, final Writer writer) 39 | throws Exception { 40 | 41 | final Integer prodId = Integer.valueOf(webExchange.getRequest().getParameterValue("prodId")); 42 | 43 | final ProductService productService = new ProductService(); 44 | final Product product = productService.findById(prodId); 45 | 46 | final WebContext ctx = new WebContext(webExchange, webExchange.getLocale()); 47 | ctx.setVariable("prod", product); 48 | 49 | templateEngine.process("product/comments", ctx, writer); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/Product.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities; 21 | 22 | import java.math.BigDecimal; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | public class Product { 27 | 28 | private Integer id = null; 29 | private String name = null; 30 | private BigDecimal price = null; 31 | private boolean inStock = false; 32 | private List comments = new ArrayList(); 33 | 34 | 35 | public Product() { 36 | super(); 37 | } 38 | 39 | 40 | public Product(final Integer id, final String name, final boolean inStock, final BigDecimal price) { 41 | super(); 42 | this.id = id; 43 | this.name = name; 44 | this.price = price; 45 | this.inStock = inStock; 46 | } 47 | 48 | 49 | public Integer getId() { 50 | return this.id; 51 | } 52 | public void setId(final Integer id) { 53 | this.id = id; 54 | } 55 | 56 | 57 | public String getName() { 58 | return this.name; 59 | } 60 | public void setName(final String name) { 61 | this.name = name; 62 | } 63 | 64 | 65 | public BigDecimal getPrice() { 66 | return this.price; 67 | } 68 | public void setPrice(final BigDecimal price) { 69 | this.price = price; 70 | } 71 | 72 | 73 | public boolean isInStock() { 74 | return this.inStock; 75 | } 76 | public void setInStock(final boolean inStock) { 77 | this.inStock = inStock; 78 | } 79 | 80 | 81 | public List getComments() { 82 | return this.comments; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/mapping/ControllerMappings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.mapping; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | import org.thymeleaf.web.IWebRequest; 26 | import thymeleafexamples.gtvg.web.controller.HomeController; 27 | import thymeleafexamples.gtvg.web.controller.IGTVGController; 28 | import thymeleafexamples.gtvg.web.controller.OrderDetailsController; 29 | import thymeleafexamples.gtvg.web.controller.OrderListController; 30 | import thymeleafexamples.gtvg.web.controller.ProductCommentsController; 31 | import thymeleafexamples.gtvg.web.controller.ProductListController; 32 | import thymeleafexamples.gtvg.web.controller.SubscribeController; 33 | import thymeleafexamples.gtvg.web.controller.UserProfileController; 34 | 35 | 36 | public class ControllerMappings { 37 | 38 | 39 | private static Map controllersByURL; 40 | 41 | 42 | static { 43 | controllersByURL = new HashMap(); 44 | controllersByURL.put("/", new HomeController()); 45 | controllersByURL.put("/product/list", new ProductListController()); 46 | controllersByURL.put("/product/comments", new ProductCommentsController()); 47 | controllersByURL.put("/order/list", new OrderListController()); 48 | controllersByURL.put("/order/details", new OrderDetailsController()); 49 | controllersByURL.put("/subscribe", new SubscribeController()); 50 | controllersByURL.put("/userprofile", new UserProfileController()); 51 | } 52 | 53 | 54 | 55 | public static IGTVGController resolveControllerForRequest(final IWebRequest request) { 56 | final String path = request.getPathWithinApplication(); 57 | return controllersByURL.get(path); 58 | } 59 | 60 | private ControllerMappings() { 61 | super(); 62 | } 63 | 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/repositories/CustomerRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities.repositories; 21 | 22 | import java.util.ArrayList; 23 | import java.util.LinkedHashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | import thymeleafexamples.gtvg.business.entities.Customer; 28 | import thymeleafexamples.gtvg.business.util.CalendarUtil; 29 | 30 | 31 | public class CustomerRepository { 32 | 33 | private static final CustomerRepository INSTANCE = new CustomerRepository(); 34 | private final Map customersById; 35 | 36 | 37 | 38 | public static CustomerRepository getInstance() { 39 | return INSTANCE; 40 | } 41 | 42 | 43 | 44 | private CustomerRepository() { 45 | 46 | super(); 47 | 48 | this.customersById = new LinkedHashMap(); 49 | 50 | final Customer cust1 = new Customer(); 51 | cust1.setId(Integer.valueOf(1)); 52 | cust1.setName("James Cucumber"); 53 | cust1.setCustomerSince(CalendarUtil.calendarFor(2006, 4, 2, 13, 20)); 54 | this.customersById.put(cust1.getId(), cust1); 55 | 56 | final Customer cust2 = new Customer(); 57 | cust2.setId(Integer.valueOf(2)); 58 | cust2.setName("Anna Lettuce"); 59 | cust2.setCustomerSince(CalendarUtil.calendarFor(2005, 1, 30, 17, 14)); 60 | this.customersById.put(cust2.getId(), cust2); 61 | 62 | final Customer cust3 = new Customer(); 63 | cust3.setId(Integer.valueOf(3)); 64 | cust3.setName("Boris Tomato"); 65 | cust3.setCustomerSince(CalendarUtil.calendarFor(2008, 12, 2, 9, 53)); 66 | this.customersById.put(cust3.getId(), cust3); 67 | 68 | final Customer cust4 = new Customer(); 69 | cust4.setId(Integer.valueOf(4)); 70 | cust4.setName("Shannon Parsley"); 71 | cust4.setCustomerSince(CalendarUtil.calendarFor(2009, 3, 24, 10, 45)); 72 | this.customersById.put(cust4.getId(), cust4); 73 | 74 | final Customer cust5 = new Customer(); 75 | cust5.setId(Integer.valueOf(5)); 76 | cust5.setName("Susan Cheddar"); 77 | cust5.setCustomerSince(CalendarUtil.calendarFor(2007, 10, 1, 15, 02)); 78 | this.customersById.put(cust5.getId(), cust5); 79 | 80 | final Customer cust6 = new Customer(); 81 | cust6.setId(Integer.valueOf(6)); 82 | cust6.setName("George Garlic"); 83 | cust6.setCustomerSince(CalendarUtil.calendarFor(2010, 5, 18, 20, 30)); 84 | this.customersById.put(cust6.getId(), cust6); 85 | 86 | } 87 | 88 | 89 | 90 | public List findAll() { 91 | return new ArrayList(this.customersById.values()); 92 | } 93 | 94 | public Customer findById(final Integer id) { 95 | return this.customersById.get(id); 96 | } 97 | 98 | 99 | 100 | } 101 | -------------------------------------------------------------------------------- /CONTRIBUTING.markdown: -------------------------------------------------------------------------------- 1 | # Contributing to Thymeleaf 2 | 3 | Thymeleaf is released under the Apache 2.0 license. If you would like to 4 | contribute something, or want to hack on the code this document should help you 5 | get started. 6 | 7 | 8 | ## Code of Conduct 9 | 10 | This project adheres to the Contributor Covenant 11 | [code of conduct][code-of-coduct]. 12 | By participating, you are expected to uphold this code. Please report 13 | unacceptable behavior to [the project leads][thymeleaf-team]. 14 | 15 | 16 | ## Using GitHub Issues 17 | 18 | We use GitHub issues to track bugs and enhancements. 19 | If you have a general usage question please ask on 20 | [Stack Overflow][stackoverflow]. 21 | The Thymeleaf team and the broader community monitor the 22 | [`thymeleaf`][stackoverflow-thymeleaf] tag. 23 | 24 | If you are reporting a bug, please help to speed up problem diagnosis by 25 | providing as much information as possible. 26 | Ideally, that would include a small sample project that reproduces the problem. 27 | 28 | 29 | ## Before submitting a Contribution 30 | 31 | Before submitting a contribution that is not an obvious or trivial fix, 32 | get in contact with the [the project leads][thymeleaf-team] about your 33 | ideas (an email should do). Let us discuss the possibilities with you so that 34 | we make sure your contribution goes in the right direction and aligns with the 35 | project's standards, intentions and roadmap. 36 | 37 | Please understand that *not all contributions will be accepted and merged into 38 | the project's repositories*. Talking about your planned contributions with the 39 | project maintainers before creating pull requests can maximize the possibility 40 | of your contributions being accepted. 41 | 42 | 43 | 44 | ## Signing the Contributor License Agreement 45 | 46 | Before we accept a non-trivial patch or pull request we will need you to 47 | sign a **Contributor License Agreement**. 48 | 49 | There are two versions of the CLA: 50 | 51 | * **Individual CLA**: For individuals acting on their own behalf, i.e. not 52 | being backed by any company or government, and not making their 53 | contributions potentially under the effect of any contracts, agreements or 54 | laws that could cause their employeer (or any other entities) claim 55 | any rights on their contribution. 56 | * **Corporate CLA**: For corporate entities allowing some of their employees 57 | to contribute to Thymeleaf on the entity's behalf. 58 | 59 | For more information on the CLA and the (very easy) process involving this 60 | step, please have a look at the [Thymeleaf CLA repository][cla]. 61 | 62 | 63 | 64 | ## Conventions and Housekeeping 65 | 66 | ### General Guidelines: 67 | 68 | - Obviously, **your code must both compile and work correctly**. 69 | - All your code should be easy to read and understand by a human. The same 70 | requirement applies to documentation. 71 | - Unless for specific artifacts such as documentation translations, all 72 | code, comments, documentation, names of classes and variables, 73 | log messages, etc. must be **in English**. 74 | - All contribured files must include the standard Thymeleaf copyright header. 75 | - Maximum recommended line length is 120 characters. This is not strictly 76 | enforced. 77 | - Indentation should be made with 4 spaces, not tabs. Line feeds should be 78 | UNIX-like (`\n`). 79 | - All source files should be pure ASCII, except `.properties` files which 80 | should be ISO-8859-1. 81 | - You shall add yourself as _author_ (e.g. Javadoc `@author`) to any files 82 | that you create or modify substantially (more than cosmetic changes). 83 | 84 | ### Specific Java Code Gudelines: 85 | 86 | - All your code should compile and run in the current minimum Java version 87 | of the project. 88 | - All your code should follow the Java Code Conventions regarding 89 | variable/method/class naming. 90 | - Number autoboxing and/or autounboxing is forbidden. 91 | - Every class should define a constructor, even if it is the no-argument 92 | constructor, and include a call to `super()`. 93 | - All method parameters should be declared as `final` so that they cannot be 94 | changed or reassigned in the method. 95 | - All non-nullable parameters in public methods should be first validated for 96 | non-nullity inside the code. 97 | - Existing Javadoc must be maintained along with performed changes. Addition 98 | of new Javadoc for public methods or code comments for any non-trivial 99 | algorithms is always welcome. 100 | - Writing unit tests for new, existing and modified code is always welcome 101 | too. For any new algorithms or functionality contributed, or substantial 102 | modifications made to existing ones, the team might consider these a 103 | requirement. 104 | 105 | 106 | 107 | 108 | [cla]: https://github.com/thymeleaf/thymeleaf-org/blob/CLA_CURRENT/CLA/ 109 | [code-of-coduct]: https://github.com/thymeleaf/thymeleaf-org/blob/CoC_CURRENT/CoC/THYMELEAF_CODE_OF_CONDUCT.markdown 110 | [thymeleaf-team]: https://www.thymeleaf.org/team.html 111 | [stackoverflow]: https://stackoverflow.com 112 | [stackoverflow-thymeleaf]: https://stackoverflow.com/tags/thymeleaf 113 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/repositories/OrderRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities.repositories; 21 | 22 | import java.math.BigDecimal; 23 | import java.util.ArrayList; 24 | import java.util.LinkedHashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | import thymeleafexamples.gtvg.business.entities.Customer; 29 | import thymeleafexamples.gtvg.business.entities.Order; 30 | import thymeleafexamples.gtvg.business.entities.OrderLine; 31 | import thymeleafexamples.gtvg.business.entities.Product; 32 | import thymeleafexamples.gtvg.business.util.CalendarUtil; 33 | 34 | 35 | public class OrderRepository { 36 | 37 | 38 | private static final OrderRepository INSTANCE = new OrderRepository(); 39 | private final Map ordersById; 40 | private final Map> ordersByCustomerId; 41 | 42 | 43 | 44 | 45 | public static OrderRepository getInstance() { 46 | return INSTANCE; 47 | } 48 | 49 | 50 | 51 | private OrderRepository() { 52 | 53 | super(); 54 | 55 | this.ordersById = new LinkedHashMap(); 56 | this.ordersByCustomerId = new LinkedHashMap>(); 57 | 58 | final Customer cust1 = CustomerRepository.getInstance().findById(Integer.valueOf(1)); 59 | this.ordersByCustomerId.put(cust1.getId(), new ArrayList()); 60 | 61 | final Customer cust4 = CustomerRepository.getInstance().findById(Integer.valueOf(4)); 62 | this.ordersByCustomerId.put(cust4.getId(), new ArrayList()); 63 | 64 | final Customer cust6 = CustomerRepository.getInstance().findById(Integer.valueOf(6)); 65 | this.ordersByCustomerId.put(cust6.getId(), new ArrayList()); 66 | 67 | 68 | final Product prod1 = ProductRepository.getInstance().findById(Integer.valueOf(1)); 69 | final Product prod2 = ProductRepository.getInstance().findById(Integer.valueOf(2)); 70 | final Product prod3 = ProductRepository.getInstance().findById(Integer.valueOf(3)); 71 | final Product prod4 = ProductRepository.getInstance().findById(Integer.valueOf(4)); 72 | 73 | 74 | final Order order1 = new Order(); 75 | order1.setId(Integer.valueOf(1)); 76 | order1.setCustomer(cust4); 77 | order1.setDate(CalendarUtil.calendarFor(2009, 1, 12, 10, 23)); 78 | this.ordersById.put(order1.getId(), order1); 79 | this.ordersByCustomerId.get(cust4.getId()).add(order1); 80 | 81 | final OrderLine orderLine11 = new OrderLine(); 82 | orderLine11.setProduct(prod2); 83 | orderLine11.setAmount(Integer.valueOf(2)); 84 | orderLine11.setPurchasePrice(new BigDecimal("0.99")); 85 | order1.getOrderLines().add(orderLine11); 86 | 87 | final OrderLine orderLine12 = new OrderLine(); 88 | orderLine12.setProduct(prod3); 89 | orderLine12.setAmount(Integer.valueOf(4)); 90 | orderLine12.setPurchasePrice(new BigDecimal("2.50")); 91 | order1.getOrderLines().add(orderLine12); 92 | 93 | final OrderLine orderLine13 = new OrderLine(); 94 | orderLine13.setProduct(prod4); 95 | orderLine13.setAmount(Integer.valueOf(1)); 96 | orderLine13.setPurchasePrice(new BigDecimal("15.50")); 97 | order1.getOrderLines().add(orderLine13); 98 | 99 | 100 | final Order order2 = new Order(); 101 | order2.setId(Integer.valueOf(2)); 102 | order2.setCustomer(cust6); 103 | order2.setDate(CalendarUtil.calendarFor(2010, 6, 9, 21, 01)); 104 | this.ordersById.put(order2.getId(), order2); 105 | this.ordersByCustomerId.get(cust6.getId()).add(order2); 106 | 107 | final OrderLine orderLine21 = new OrderLine(); 108 | orderLine21.setProduct(prod1); 109 | orderLine21.setAmount(Integer.valueOf(5)); 110 | orderLine21.setPurchasePrice(new BigDecimal("3.75")); 111 | order2.getOrderLines().add(orderLine21); 112 | 113 | final OrderLine orderLine22 = new OrderLine(); 114 | orderLine22.setProduct(prod4); 115 | orderLine22.setAmount(Integer.valueOf(2)); 116 | orderLine22.setPurchasePrice(new BigDecimal("17.99")); 117 | order2.getOrderLines().add(orderLine22); 118 | 119 | 120 | 121 | final Order order3 = new Order(); 122 | order3.setId(Integer.valueOf(3)); 123 | order3.setCustomer(cust1); 124 | order3.setDate(CalendarUtil.calendarFor(2010, 7, 18, 22, 32)); 125 | this.ordersById.put(order3.getId(), order3); 126 | this.ordersByCustomerId.get(cust4.getId()).add(order3); 127 | 128 | final OrderLine orderLine32 = new OrderLine(); 129 | orderLine32.setProduct(prod1); 130 | orderLine32.setAmount(Integer.valueOf(8)); 131 | orderLine32.setPurchasePrice(new BigDecimal("5.99")); 132 | order3.getOrderLines().add(orderLine32); 133 | 134 | 135 | } 136 | 137 | 138 | 139 | public List findAll() { 140 | return new ArrayList(this.ordersById.values()); 141 | } 142 | 143 | public Order findById(final Integer id) { 144 | return this.ordersById.get(id); 145 | } 146 | 147 | 148 | public List findByCustomerId(final Integer customerId) { 149 | final List ordersForCustomerId = this.ordersByCustomerId.get(customerId); 150 | if (ordersForCustomerId == null) { 151 | return new ArrayList(); 152 | } 153 | return ordersForCustomerId; 154 | } 155 | 156 | 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/web/filter/GTVGFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.web.filter; 21 | 22 | import java.io.IOException; 23 | import java.io.Writer; 24 | 25 | import jakarta.servlet.Filter; 26 | import jakarta.servlet.FilterChain; 27 | import jakarta.servlet.FilterConfig; 28 | import jakarta.servlet.ServletException; 29 | import jakarta.servlet.ServletRequest; 30 | import jakarta.servlet.ServletResponse; 31 | import jakarta.servlet.http.HttpServletRequest; 32 | import jakarta.servlet.http.HttpServletResponse; 33 | import org.thymeleaf.ITemplateEngine; 34 | import org.thymeleaf.TemplateEngine; 35 | import org.thymeleaf.templatemode.TemplateMode; 36 | import org.thymeleaf.templateresolver.WebApplicationTemplateResolver; 37 | import org.thymeleaf.web.IWebApplication; 38 | import org.thymeleaf.web.IWebExchange; 39 | import org.thymeleaf.web.IWebRequest; 40 | import org.thymeleaf.web.servlet.JakartaServletWebApplication; 41 | import thymeleafexamples.gtvg.business.entities.User; 42 | import thymeleafexamples.gtvg.web.controller.IGTVGController; 43 | import thymeleafexamples.gtvg.web.mapping.ControllerMappings; 44 | 45 | 46 | public class GTVGFilter implements Filter { 47 | 48 | private ITemplateEngine templateEngine; 49 | private JakartaServletWebApplication application; 50 | 51 | 52 | public GTVGFilter() { 53 | super(); 54 | } 55 | 56 | 57 | 58 | private static void addUserToSession(final HttpServletRequest request) { 59 | // Simulate a real user session by adding a user object 60 | request.getSession(true).setAttribute("user", new User("John", "Apricot", "Antarctica", null)); 61 | } 62 | 63 | 64 | 65 | 66 | public void init(final FilterConfig filterConfig) throws ServletException { 67 | this.application = 68 | JakartaServletWebApplication.buildApplication(filterConfig.getServletContext()); 69 | this.templateEngine = buildTemplateEngine(this.application); 70 | } 71 | 72 | 73 | 74 | 75 | public void doFilter(final ServletRequest request, final ServletResponse response, 76 | final FilterChain chain) throws IOException, ServletException { 77 | addUserToSession((HttpServletRequest)request); 78 | if (!process((HttpServletRequest)request, (HttpServletResponse)response)) { 79 | chain.doFilter(request, response); 80 | } 81 | } 82 | 83 | 84 | 85 | 86 | public void destroy() { 87 | // nothing to do 88 | } 89 | 90 | 91 | 92 | 93 | private boolean process(final HttpServletRequest request, final HttpServletResponse response) 94 | throws ServletException { 95 | 96 | try { 97 | 98 | final IWebExchange webExchange = this.application.buildExchange(request, response); 99 | final IWebRequest webRequest = webExchange.getRequest(); 100 | 101 | // This prevents triggering engine executions for resource URLs 102 | if (webRequest.getPathWithinApplication().startsWith("/css") || 103 | webRequest.getPathWithinApplication().startsWith("/images") || 104 | webRequest.getPathWithinApplication().startsWith("/favicon")) { 105 | return false; 106 | } 107 | 108 | 109 | /* 110 | * Query controller/URL mapping and obtain the controller 111 | * that will process the request. If no controller is available, 112 | * return false and let other filters/servlets process the request. 113 | */ 114 | final IGTVGController controller = ControllerMappings.resolveControllerForRequest(webRequest); 115 | if (controller == null) { 116 | return false; 117 | } 118 | 119 | /* 120 | * Write the response headers 121 | */ 122 | response.setContentType("text/html;charset=UTF-8"); 123 | response.setHeader("Pragma", "no-cache"); 124 | response.setHeader("Cache-Control", "no-cache"); 125 | response.setDateHeader("Expires", 0); 126 | 127 | /* 128 | * Obtain the response writer 129 | */ 130 | final Writer writer = response.getWriter(); 131 | 132 | /* 133 | * Execute the controller and process view template, 134 | * writing the results to the response writer. 135 | */ 136 | controller.process(webExchange, this.templateEngine, writer); 137 | 138 | return true; 139 | 140 | } catch (final Exception e) { 141 | try { 142 | response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 143 | } catch (final IOException ignored) { 144 | // Just ignore this 145 | } 146 | throw new ServletException(e); 147 | } 148 | 149 | } 150 | 151 | 152 | private static ITemplateEngine buildTemplateEngine(final IWebApplication application) { 153 | 154 | final WebApplicationTemplateResolver templateResolver = new WebApplicationTemplateResolver(application); 155 | 156 | // HTML is the default mode, but we will set it anyway for better understanding of code 157 | templateResolver.setTemplateMode(TemplateMode.HTML); 158 | // This will convert "home" to "/WEB-INF/templates/home.html" 159 | templateResolver.setPrefix("/WEB-INF/templates/"); 160 | templateResolver.setSuffix(".html"); 161 | // Set template cache TTL to 1 hour. If not set, entries would live in cache until expelled by LRU 162 | templateResolver.setCacheTTLMs(Long.valueOf(3600000L)); 163 | 164 | // Cache is set to true by default. Set to false if you want templates to 165 | // be automatically updated when modified. 166 | templateResolver.setCacheable(true); 167 | 168 | final TemplateEngine templateEngine = new TemplateEngine(); 169 | templateEngine.setTemplateResolver(templateResolver); 170 | 171 | return templateEngine; 172 | 173 | } 174 | 175 | } 176 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 4.0.0 25 | thymeleafexamples 26 | gtvg 27 | war 28 | ci 29 | Thymeleaf Examples - Good Thymes Virtual Grocery 30 | 31 | Modern server-side Java template engine for both web and standalone environments 32 | 33 | 34 | 35 | The Apache Software License, Version 2.0 36 | http://www.apache.org/licenses/LICENSE-2.0.txt 37 | repo 38 | 39 | 40 | 41 | 42 | The THYMELEAF team 43 | http://www.thymeleaf.org 44 | 45 | 46 | 47 | scm:git:git@github.com:thymeleaf/thymeleafexamples-gtvg.git 48 | scm:git:git@github.com:thymeleaf/thymeleafexamples-gtvg.git 49 | scm:git:git@github.com:thymeleaf/thymeleafexamples-gtvg.git 50 | 51 | 52 | 53 | 54 | danielfernandez 55 | Daniel Fernandez 56 | daniel.fernandez AT 11thlabs DOT org 57 | 58 | Project Admin 59 | Lead Developer 60 | 61 | 62 | 63 | jmiguelsamper 64 | Jose Miguel Samper 65 | jmiguelsamper AT users DOT sourceforge DOT net 66 | 67 | Developer 68 | 69 | 70 | 71 | ultraq 72 | Emanuel Rabina 73 | emanuelrabina AT gmail DOT com 74 | 75 | Developer 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | sonatype-nexus-snapshots 84 | Sonatype Nexus Snapshots 85 | https://oss.sonatype.org/content/repositories/snapshots 86 | 87 | true 88 | 89 | 90 | 91 | 92 | 93 | 94 | 8 95 | ${java.version} 96 | ${java.version} 97 | ${java.version} 98 | US-ASCII 99 | 3.1.0-SNAPSHOT 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | src/main/resources 109 | 110 | 111 | src/main/java 112 | 113 | **/*.properties 114 | **/*.xml 115 | **/*.html 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | org.apache.maven.plugins 126 | maven-compiler-plugin 127 | 3.8.1 128 | 129 | 130 | 131 | org.apache.maven.plugins 132 | maven-resources-plugin 133 | 3.2.0 134 | 135 | 136 | 137 | org.apache.maven.plugins 138 | maven-war-plugin 139 | 3.3.2 140 | 141 | false 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | build-dist 154 | 155 | 156 | 157 | org.apache.maven.plugins 158 | maven-assembly-plugin 159 | 3.1.0 160 | 161 | 162 | make-assembly-dist 163 | package 164 | 165 | single 166 | 167 | 168 | 169 | ${basedir}/src/assembly/sources.xml 170 | 171 | true 172 | ${project.groupId}-${project.artifactId}-${project.version} 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | org.thymeleaf 189 | thymeleaf 190 | ${thymeleaf.version} 191 | compile 192 | 193 | 194 | 195 | 196 | jakarta.servlet 197 | jakarta.servlet-api 198 | 5.0.0 199 | provided 200 | 201 | 202 | 203 | org.slf4j 204 | slf4j-api 205 | 1.7.32 206 | compile 207 | 208 | 209 | 210 | org.slf4j 211 | slf4j-log4j12 212 | 1.7.32 213 | compile 214 | 215 | 216 | 217 | log4j 218 | log4j 219 | 1.2.17 220 | compile 221 | 222 | 223 | com.sun.jdmk 224 | jmxtools 225 | 226 | 227 | com.sun.jmx 228 | jmxri 229 | 230 | 231 | javax.jms 232 | jms 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /src/main/java/thymeleafexamples/gtvg/business/entities/repositories/ProductRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) 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 | */ 20 | package thymeleafexamples.gtvg.business.entities.repositories; 21 | 22 | import java.math.BigDecimal; 23 | import java.util.ArrayList; 24 | import java.util.LinkedHashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | import thymeleafexamples.gtvg.business.entities.Comment; 29 | import thymeleafexamples.gtvg.business.entities.Product; 30 | 31 | 32 | public class ProductRepository { 33 | 34 | private static final ProductRepository INSTANCE = new ProductRepository(); 35 | private final Map productsById; 36 | 37 | 38 | 39 | public static ProductRepository getInstance() { 40 | return INSTANCE; 41 | } 42 | 43 | 44 | private ProductRepository() { 45 | 46 | super(); 47 | 48 | this.productsById = new LinkedHashMap(); 49 | 50 | 51 | final Product prod1 = new Product(1, "Fresh Sweet Basil", true, new BigDecimal("4.99")); 52 | final Product prod2 = new Product(2, "Italian Tomato", false, new BigDecimal("1.25")); 53 | final Product prod3 = new Product(3, "Yellow Bell Pepper", true, new BigDecimal("2.50")); 54 | final Product prod4 = new Product(4, "Old Cheddar", true, new BigDecimal("18.75")); 55 | final Product prod5 = new Product(5, "Extra Virgin Coconut Oil", true, new BigDecimal("6.34")); 56 | final Product prod6 = new Product(6, "Organic Tomato Ketchup", true, new BigDecimal("1.99")); 57 | final Product prod7 = new Product(7, "Whole Grain Oatmeal Cereal", true, new BigDecimal("3.07")); 58 | final Product prod8 = new Product(8, "Traditional Tomato & Basil Sauce", true, new BigDecimal("2.58")); 59 | final Product prod9 = new Product(9, "Quinoa Flour", true, new BigDecimal("3.02")); 60 | final Product prod10 = new Product(10, "Grapefruit Juice", true, new BigDecimal("2.58")); 61 | final Product prod11 = new Product(11, "100% Pure Maple Syrup", true, new BigDecimal("5.98")); 62 | final Product prod12 = new Product(12, "Marinara Pasta Sauce", false, new BigDecimal("2.08")); 63 | final Product prod13 = new Product(13, "Vanilla Puff Cereal", false, new BigDecimal("1.75")); 64 | final Product prod14 = new Product(14, "Extra Virgin Oil", false, new BigDecimal("5.01")); 65 | final Product prod15 = new Product(15, "Roasted Garlic Pasta Sauce", true, new BigDecimal("2.40")); 66 | final Product prod16 = new Product(16, "Canned Minestrone Soup", true, new BigDecimal("2.19")); 67 | final Product prod17 = new Product(17, "Almond Milk 1L", true, new BigDecimal("3.24")); 68 | final Product prod18 = new Product(18, "Organic Chicken & Wild Rice Soup", true, new BigDecimal("3.17")); 69 | final Product prod19 = new Product(19, "Purple Carrot, Blackberry, Quinoa & Greek Yogurt", true, new BigDecimal("8.88")); 70 | final Product prod20 = new Product(20, "Pumpkin, Carrot and Apple Juice", false, new BigDecimal("3.90")); 71 | final Product prod21 = new Product(21, "Organic Canola Oil", true, new BigDecimal("10.13")); 72 | final Product prod22 = new Product(22, "Potato Corn Tortilla Chips", true, new BigDecimal("2.44")); 73 | final Product prod23 = new Product(23, "Canned Corn Chowder Soup", true, new BigDecimal("2.30")); 74 | final Product prod24 = new Product(24, "Organic Lemonade Juice", true, new BigDecimal("2.48")); 75 | final Product prod25 = new Product(25, "Spicy Basil Dressing", true, new BigDecimal("4.72")); 76 | final Product prod26 = new Product(26, "Sweet Agave Nectar", true, new BigDecimal("6.46")); 77 | final Product prod27 = new Product(27, "Dark Roasted Peanut Butter", false, new BigDecimal("3.48")); 78 | final Product prod28 = new Product(28, "Unsweetened Lemon Green Tea", true, new BigDecimal("18.34")); 79 | final Product prod29 = new Product(29, "Whole Grain Flakes Cereal", true, new BigDecimal("3.52")); 80 | final Product prod30 = new Product(30, "Berry Chewy Granola Bars", true, new BigDecimal("4.00")); 81 | 82 | 83 | this.productsById.put(prod1.getId(), prod1); 84 | this.productsById.put(prod2.getId(), prod2); 85 | this.productsById.put(prod3.getId(), prod3); 86 | this.productsById.put(prod4.getId(), prod4); 87 | this.productsById.put(prod5.getId(), prod5); 88 | this.productsById.put(prod6.getId(), prod6); 89 | this.productsById.put(prod7.getId(), prod7); 90 | this.productsById.put(prod8.getId(), prod8); 91 | this.productsById.put(prod9.getId(), prod9); 92 | this.productsById.put(prod10.getId(), prod10); 93 | this.productsById.put(prod11.getId(), prod11); 94 | this.productsById.put(prod12.getId(), prod12); 95 | this.productsById.put(prod13.getId(), prod13); 96 | this.productsById.put(prod14.getId(), prod14); 97 | this.productsById.put(prod15.getId(), prod15); 98 | this.productsById.put(prod16.getId(), prod16); 99 | this.productsById.put(prod17.getId(), prod17); 100 | this.productsById.put(prod18.getId(), prod18); 101 | this.productsById.put(prod19.getId(), prod19); 102 | this.productsById.put(prod20.getId(), prod20); 103 | this.productsById.put(prod21.getId(), prod21); 104 | this.productsById.put(prod22.getId(), prod22); 105 | this.productsById.put(prod23.getId(), prod23); 106 | this.productsById.put(prod24.getId(), prod24); 107 | this.productsById.put(prod25.getId(), prod25); 108 | this.productsById.put(prod26.getId(), prod26); 109 | this.productsById.put(prod27.getId(), prod27); 110 | this.productsById.put(prod28.getId(), prod28); 111 | this.productsById.put(prod29.getId(), prod29); 112 | this.productsById.put(prod30.getId(), prod30); 113 | 114 | 115 | prod2.getComments().add(new Comment(1, "I'm so sad this product is no longer available!")); 116 | prod2.getComments().add(new Comment(2, "When do you expect to have it back?")); 117 | 118 | prod13.getComments().add(new Comment(3, "Very tasty! I'd definitely buy it again!")); 119 | prod13.getComments().add(new Comment(4, "My kids love it!")); 120 | prod13.getComments().add(new Comment(5, "Good, my basic breakfast cereal. Though maybe a bit in the sweet side...")); 121 | prod13.getComments().add(new Comment(6, "Not that I find it bad, but I think the vanilla flavouring is too intrusive")); 122 | prod13.getComments().add(new Comment(7, "I agree with the excessive flavouring, but still one of my favourites!")); 123 | prod13.getComments().add(new Comment(8, "Cheaper than at the local store!")); 124 | prod13.getComments().add(new Comment(9, "I'm sorry to disagree, but IMO these are far too sweet")); 125 | prod13.getComments().add(new Comment(10, "Good. Pricey though.")); 126 | 127 | 128 | prod9.getComments().add(new Comment(11, "Made bread with this and it was great!")); 129 | prod9.getComments().add(new Comment(12, "Note: this comes actually mixed with wheat flour")); 130 | 131 | prod14.getComments().add(new Comment(13, "Awesome Spanish oil. Buy it now.")); 132 | prod14.getComments().add(new Comment(14, "Would definitely buy it again. Best one I've tasted")); 133 | prod14.getComments().add(new Comment(15, "A bit acid for my taste, but still a very nice one.")); 134 | prod14.getComments().add(new Comment(16, "Definitely not the average olive oil. Really good.")); 135 | 136 | prod16.getComments().add(new Comment(17, "Great value!")); 137 | 138 | prod24.getComments().add(new Comment(18, "My favourite :)")); 139 | 140 | prod30.getComments().add(new Comment(19, "Too hard! I would not buy again")); 141 | prod30.getComments().add(new Comment(20, "Taste is OK, but I agree with previous comment that bars are too hard to eat")); 142 | prod30.getComments().add(new Comment(21, "Would definitely NOT buy again. Simply unedible!")); 143 | 144 | 145 | } 146 | 147 | 148 | 149 | public List findAll() { 150 | return new ArrayList(this.productsById.values()); 151 | } 152 | 153 | public Product findById(final Integer id) { 154 | return this.productsById.get(id); 155 | } 156 | 157 | 158 | 159 | } 160 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | --------------------------------------------------------------------------------