-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
57fba66
commit ac16374
Showing
15 changed files
with
324 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,4 +36,7 @@ bin/ | |
.vscode/ | ||
|
||
### Mac OS ### | ||
.DS_Store | ||
.DS_Store | ||
|
||
### Jte ### | ||
jte-classes/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
app/src/main/java/hexlet/code/controller/UrlsController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package hexlet.code.controller; | ||
|
||
import hexlet.code.dto.urls.UrlPage; | ||
import hexlet.code.dto.urls.UrlsPage; | ||
import hexlet.code.model.Url; | ||
import hexlet.code.repository.UrlRepository; | ||
import hexlet.code.util.NamedRoutes; | ||
import io.javalin.http.Context; | ||
import io.javalin.http.NotFoundResponse; | ||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.sql.SQLException; | ||
import java.sql.Timestamp; | ||
import java.time.LocalDateTime; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
public class UrlsController { | ||
private static final int ITEMS_PER_PAGE = 10; | ||
|
||
public static void build(Context ctx) { | ||
ctx.render("urls/build.jte"); | ||
} | ||
|
||
public static void create(Context ctx) throws SQLException { | ||
|
||
try { | ||
var formUrl = new URL(ctx.formParamAsClass("name", String.class).get()); | ||
var name = formUrl.getProtocol() + "://" + formUrl.getAuthority(); | ||
var createdAt = new Timestamp(System.currentTimeMillis()); | ||
var url = new Url(name, createdAt); | ||
|
||
if (UrlRepository.existsByName(name)) { | ||
ctx.sessionAttribute("message", "Страница уже существует"); | ||
} else { | ||
UrlRepository.save(url); | ||
ctx.sessionAttribute("message", "Страница успешно добавлена"); | ||
} | ||
ctx.redirect(NamedRoutes.urlsPath()); | ||
} catch (MalformedURLException e) { | ||
ctx.sessionAttribute("message", "Некорректный URL"); | ||
ctx.redirect(NamedRoutes.rootPath()); | ||
} | ||
} | ||
|
||
public static void index(Context ctx) throws SQLException { | ||
var urls = UrlRepository.getEntities(); | ||
var pageNumber = ctx.queryParamAsClass("page", Integer.class).getOrDefault(1); | ||
var page = new UrlsPage(urls, pageNumber, ITEMS_PER_PAGE); | ||
String message = ctx.consumeSessionAttribute("message"); | ||
page.setMessage(message); | ||
ctx.render("urls/index.jte", Collections.singletonMap("page", page)); | ||
} | ||
|
||
public static void show(Context ctx) throws SQLException { | ||
var id = ctx.pathParamAsClass("id", Long.class).get(); | ||
var url = UrlRepository.find(id) | ||
.orElseThrow(() -> new NotFoundResponse("Запись с таким ID не найдена")); | ||
var page = new UrlPage(url); | ||
ctx.render("urls/show.jte", Collections.singletonMap("page", page)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package hexlet.code.dto; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
@Getter | ||
@Setter | ||
public class BasePage { | ||
private String message; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package hexlet.code.dto.urls; | ||
|
||
import hexlet.code.model.Url; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@AllArgsConstructor | ||
@Getter | ||
public class UrlPage { | ||
private Url url; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package hexlet.code.dto.urls; | ||
|
||
import hexlet.code.dto.BasePage; | ||
import hexlet.code.model.Url; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
import java.util.List; | ||
|
||
@AllArgsConstructor | ||
@Getter | ||
public class UrlsPage extends BasePage { | ||
private List<Url> urls; | ||
private int page; | ||
private int itemsPerPage; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
app/src/main/java/hexlet/code/repository/UrlRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package hexlet.code.repository; | ||
|
||
import hexlet.code.model.Url; | ||
|
||
import java.sql.SQLException; | ||
import java.sql.Statement; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
public class UrlRepository extends BaseRepository { | ||
|
||
public static void save(Url url) throws SQLException { | ||
var sql = "INSERT INTO urls (name, created_at) VALUES (?, ?)"; | ||
try (var conn = dataSource.getConnection(); | ||
var preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { | ||
|
||
preparedStatement.setString(1, url.getName()); | ||
preparedStatement.setTimestamp(2, url.getCreatedAt()); | ||
preparedStatement.executeUpdate(); | ||
|
||
var generatedKeys = preparedStatement.getGeneratedKeys(); | ||
if (generatedKeys.next()) { | ||
url.setId(generatedKeys.getLong(1)); | ||
} else { | ||
throw new SQLException("Не сформирован ID"); | ||
} | ||
} | ||
} | ||
|
||
public static Optional<Url> find(Long id) throws SQLException { | ||
var sql = "SELECT * FROM urls WHERE id = ?"; | ||
try (var conn = dataSource.getConnection(); | ||
var stmt = conn.prepareStatement(sql)) { | ||
|
||
stmt.setLong(1, id); | ||
var resultSet = stmt.executeQuery(); | ||
if (resultSet.next()) { | ||
var name = resultSet.getString("name"); | ||
var createdAt = resultSet.getTimestamp("created_at"); | ||
var url = new Url(name, createdAt); | ||
url.setId(id); | ||
return Optional.of(url); | ||
} | ||
return Optional.empty(); | ||
} | ||
} | ||
|
||
public static boolean existsByName(String name) throws SQLException { | ||
var sql = "SELECT * FROM urls WHERE name = ?"; | ||
try (var conn = dataSource.getConnection(); | ||
var stmt = conn.prepareStatement(sql)) { | ||
|
||
stmt.setString(1, name); | ||
var resultSet = stmt.executeQuery(); | ||
return resultSet.next(); | ||
} | ||
} | ||
|
||
public static List<Url> getEntities() throws SQLException { | ||
var sql = "SELECT * FROM urls"; | ||
try (var conn = dataSource.getConnection(); | ||
var stmt = conn.prepareStatement(sql)) { | ||
|
||
var resultSet = stmt.executeQuery(); | ||
var result = new ArrayList<Url>(); | ||
|
||
while (resultSet.next()) { | ||
var id = resultSet.getLong("id"); | ||
var name = resultSet.getString("name"); | ||
var createdAt = resultSet.getTimestamp("created_at"); | ||
var url = new Url(name, createdAt); | ||
url.setId(id); | ||
result.add(url); | ||
} | ||
return result; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
@import hexlet.code.util.NamedRoutes | ||
|
||
@template.layout.page( | ||
content = @` | ||
<form action="${NamedRoutes.rootPath()}" method="post"> | ||
<h6>Введите адрес ссылки:</h6> | ||
<div class="form-floating row row-cols-lg-auto g-3 align-items-center"> | ||
<label for="inputUrl" class="form-label">Ссылка</label> | ||
<input type="url" class="form-control" id="inputUrl" name="name"> | ||
<div class="form-text">Пример: https://www.example.com</div> | ||
</div> | ||
<div> | ||
<button type="submit" class="btn btn-primary">Проверить</button> | ||
</div> | ||
</form> | ||
` | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
@import hexlet.code.util.NamedRoutes | ||
@import hexlet.code.model.Url | ||
@import hexlet.code.dto.urls.UrlsPage | ||
@param UrlsPage page | ||
|
||
@template.layout.page( | ||
content = @` | ||
!{var message = page.getMessage();} | ||
@if(message != null) | ||
@if(message.contains("успешно")) | ||
<div class="alert alert-success shadow-sm p-3 mb-5 bg-body rounded" role="alert"> | ||
${message} | ||
<button type="button" class="btn-close position-absolute top-50 start-100 translate-middle" aria-label="Close"></button> | ||
</div> | ||
@elseif(message.contains("уже")) | ||
<div class="alert alert-warning shadow-sm p-3 mb-5 bg-body rounded" role="alert"> | ||
${message} | ||
<button type="button" class="btn-close position-absolute top-50 start-100 translate-middle" aria-label="Close"></button> | ||
</div> | ||
@endif | ||
@endif | ||
|
||
!{var pageCount = page.getUrls().size() / page.getItemsPerPage();} | ||
|
||
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups"> | ||
@for(int i = 1; i < pageCount; i++) | ||
<button type="button" class="btn btn-primary"><a href="${NamedRoutes.urlsPath(i)}">i</a></button> | ||
@endfor | ||
</div> | ||
|
||
!{var urls = page.getUrls();} | ||
@if(!urls.isEmpty()) | ||
<table class="table table-light table-hover table-striped table-bordered border-success"> | ||
<thead> | ||
<tr> | ||
<th scope="col">ID</th> | ||
<th scope="col">Название</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
@for(Url item : urls) | ||
<tr> | ||
<th scope="row">${item.getId()}</th> | ||
<td>${item.getName()}</td> | ||
</tr> | ||
@endfor | ||
</tbody> | ||
</table> | ||
@else | ||
<div class="alert alert-warning shadow-sm p-3 mb-5 bg-body rounded" role="alert"> | ||
Список пуст | ||
<button type="button" class="btn-close position-absolute top-50 start-100 translate-middle" aria-label="Close"></button> | ||
</div> | ||
@endif | ||
|
||
` | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
@import hexlet.code.dto.urls.UrlPage | ||
@param UrlPage page | ||
|
||
@template.layout.page( | ||
content = @` | ||
<div class="fw-bold"> | ||
<h1>Сайт ${page.getUrl().getName()}</h1> | ||
</div> | ||
<table class="table table-light table-hover border border-light border-2"> | ||
<tbody> | ||
<tr> | ||
<th scope="row">ID</th> | ||
<td>${page.getUrl().getId()}</td> | ||
</tr> | ||
<tr> | ||
<th scope="row">Название</th> | ||
<td>${page.getUrl().getName()}</td> | ||
</tr> | ||
<tr> | ||
<th scope="row">Дата добавления</th> | ||
<td>${page.getUrl().getCreatedAt().toString()}</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
` | ||
) |