Merge branch 'master' into 4-db

# Conflicts:
#	src/main/resources/application.properties
This commit is contained in:
Anton Romanov 2021-03-17 09:15:10 +04:00
commit 4f5a096a5e
14 changed files with 332 additions and 2 deletions

View File

@ -39,8 +39,6 @@ repositories {
configurations {
compile.exclude module: "spring-boot-starter-tomcat"
compile.exclude module: "jquery"
compile.exclude module: "popper.js"
compile.exclude module: "follow-redirects"
compile.exclude module: "is-buffer"
}
@ -48,6 +46,8 @@ configurations {
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
compile group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect'
compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-afterburner'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc'
@ -58,6 +58,12 @@ dependencies {
compile group: 'com.ibm.icu', name: 'icu4j', version: '63.1'
compile group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '5.9.0.202009080501-r'
compile group: 'org.webjars', name: 'jquery', version: '3.6.0'
compile group: 'org.webjars', name: 'bootstrap', version: '4.6.0'
compile group: 'org.webjars', name: 'bootstrap-select', version: '1.13.8'
compile group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
}

View File

@ -0,0 +1,26 @@
package ru.ulstu.extractor.mvc;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import ru.ulstu.extractor.mvc.model.EmailForm;
@Controller
public class GitExtractorController {
@GetMapping("/")
public String indexForm(Model model) {
model.addAttribute("emailForm", new EmailForm());
return "index";
}
@PostMapping("/sendEmail")
public String sendEmail(@ModelAttribute EmailForm emailForm, Model model) {
if (emailForm.getTo().isEmpty()) {
model.addAttribute("error", "'Кому' не должно быть пустым");
return "index";
}
return "result";
}
}

View File

@ -0,0 +1,30 @@
package ru.ulstu.extractor.mvc;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
@ControllerAdvice
class GlobalDefaultExceptionHandler {
public static final String DEFAULT_ERROR_VIEW = "error";
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) {
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", req.getRequestURL());
mav.setViewName(DEFAULT_ERROR_VIEW);
return mav;
}
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handle(NoHandlerFoundException ex) {
return "DEFAULT_ERROR_VIEW";
}
}

View File

@ -0,0 +1,23 @@
package ru.ulstu.extractor.mvc;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{articlename:\\w+}");
registry.addRedirectViewController("/", "/index");
registry.addRedirectViewController("/default", "/home");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/");
}
}

View File

@ -0,0 +1,33 @@
package ru.ulstu.extractor.mvc;
import nz.net.ultraq.thymeleaf.LayoutDialect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.templateresolver.ITemplateResolver;
@Configuration
public class TemplateConfiguration {
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(templateResolver);
templateEngine.addDialect(new LayoutDialect());
templateEngine.setMessageSource(messageSource());
return templateEngine;
}
@Value("${messages.basename.path}")
private String messagesBasename;
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setFallbackToSystemLocale(false);
messageSource.setBasenames("file:" + messagesBasename);
return messageSource;
}
}

View File

@ -0,0 +1,40 @@
package ru.ulstu.extractor.mvc.model;
public class EmailForm {
private String subject;
private String to;
private String message;
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "EmailForm{" +
"subject='" + subject + '\'' +
", to='" + to + '\'' +
", message='" + message + '\'' +
'}';
}
}

View File

@ -3,6 +3,9 @@ server.port=8080
# Available levels are: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
logging.level.ru.ulstu=DEBUG
extractor.custom-projects-dir=
# Thymeleaf Settings
spring.thymeleaf.cache=false
messages.basename.path=messages_en.properties
# JPA Settings
spring.datasource.url=jdbc:postgresql://localhost:5432/repo
spring.datasource.username=postgres

View File

@ -0,0 +1,4 @@
messages.app-name=GitExtractor v0.1.0
messages.menu.home=Main
messages.menu.indexed-repos=List of indexed repos
messages.menu.new-repo=Analyse new repo

View File

@ -0,0 +1,4 @@
messages.app-name=GitExtractor v0.1.0
messages.menu.home=Main
messages.menu.indexed-repos=List of indexed repos
messages.menu.new-repo=Analyse new repo

View File

@ -0,0 +1,4 @@
messages.app-name=GitЁxtractor v0.1.0
messages.menu.home=На главную
messages.menu.indexed-repos=Список проиндексированных репозиториев
messages.menu.new-repo=Анализ нового репозитория

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="ru"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title th:text="#{messages.app-name}">app-name</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script type="text/javascript" src="/webjars/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/4.6.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap-select/1.13.8/js/bootstrap-select.min.js"></script>
<link rel="stylesheet" href="/webjars/bootstrap/4.6.0/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/webjars/bootstrap-select/1.13.8/css/bootstrap-select.min.css"/>
<link rel="stylesheet" href="/webjars/font-awesome/4.7.0/css/font-awesome.min.css"/>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light" layout:fragment="navbar">
<a class="navbar-brand" href="/" th:text="#{messages.app-name}">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/" th:text="#{messages.menu.home}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:text="#{messages.menu.new-repo}">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:text="#{messages.menu.indexed-repos}">Link</a>
</li>
</ul>
</div>
</nav>
<div class="wrapper">
<div id="sidebar" class="collapse navbar-collapse sidebar-mobile">
<ul id="menu" class="list-unstyled">
</ul>
</div>
<div id="content">
<div id="breadcrumbs" class="container-fluid">
</div>
<div class="container-fluid">
<ul id="messages" class="feedback-panel">
</ul>
</div>
<div layout:fragment="content">
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,45 @@
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<!--<head th:substituteby="header :: copy"></head>-->
<div class="container" layout:fragment="content">
<h1>Ошибка</h1>
<!-- As we are using Thymeleaf, you might consider using
${#httpServletRequest.requestURL}. But that returns the path
to this error page. Hence we explicitly add the url to the
Model in some of the example code. -->
<p th:if="${url}">
<b>Страница:</b> <span th:text="${url}">Page URL</span>
</p>
<p th:if="${timestamp}" id='created'>
<b>Время:</b> <span th:text="${timestamp}">Timestamp</span>
</p>
<p th:if="${status}">
<b>Response Status:</b> <span th:text="${status}">status-code</span> <span
th:if="${error}" th:text="'('+${error}+')'">error ...</span>
</p>
<p>
<a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false"
aria-controls="collapseExample">
Показать stack trace
</a>
</p>
<div class="collapse" id="collapseExample">
<div class="card card-body">
<div th:utext="'Failed URL: ' + ${url}" th:remove="tag">${url}</div>
<div th:utext="'Exception: ' + ${exception.message}" th:remove="tag">${exception.message}</div>
<ul th:remove="tag">
<li th:each="ste : ${exception.stackTrace}" th:remove="tag"><span
th:utext="${ste}" th:remove="tag">${ste}</span></li>
</ul>
</div>
</div>
</div>
</html>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
<title>Простая обработка формы на Spring MVC</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<div class="container" layout:fragment="content">
<h1>Форма</h1>
<form action="#" th:action="@{/sendEmail}" th:object="${emailForm}" method="post">
<p style="color:red" th:text="${error}"></p>
<table>
<tr>
<td>Тема:</td>
<td><input type="text" th:field="*{subject}"/></td>
</tr>
<tr>
<td>Кому:</td>
<td><input type="text" th:field="*{to}"/></td>
</tr>
<tr>
<td>Сообщение:</td>
<td><textarea th:field="*{message}"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Отправить"/></td>
</tr>
</table>
</form>
</div>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Простая обработка формы на Spring MVC</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<h1>Результат обработки формы</h1>
<table>
<tr>
<td>Тема:</td>
<td><p th:text="${emailForm.subject}"/></td>
</tr>
<tr>
<td>Кому:</td>
<td><p th:text="${emailForm.to}"/></td>
</tr>
<tr>
<td>Сообщение:</td>
<td><p th:text="${emailForm.message}"/></td>
</tr>
</table>
<a href="/">Отправить другое сообщение</a>
</body>
</html>