diff --git a/README.MD b/README.MD deleted file mode 100644 index 1bf1eca..0000000 --- a/README.MD +++ /dev/null @@ -1,28 +0,0 @@ -# Quest Pantera - -### Ребята и девчата, всем привет! - -На этот раз у нас более сложный проект, который будет трудно объединить в один общий проект со всем зависимостями. -Поэтому поступим просто. Тут первоначально лежит наш учебный проект. -Заготовка, такая же как может быть сгенерирована в IDEA. -Договоримся, что Java у нас будет 21-я. У всех. Привыкайте использовать только LTS. -Из зависимостей есть jakarta.servlet-api + jstl, JUnit5 и Lombok, -так что POM.xml возможно надо будет заменить на свой. - -### Что нужно сделать. - -1. Сделайте форк и затем клон этого репозитория. -2. **СРАЗУ** создайте в нем ветку со своей фамилией, например, ivanov. -3. Размещайте в своей ветке свое решение (если мои примеры мешают их можно просто удалить - ветвление же). -4. В конце вам нужно будет сделать **Pull Request** из своей ветки (в своем форке) в такую же точно ветку (в этом удаленном - репозитории), если вы не найдете - тогда в **main** ну и затем ОБЯЗАТЕЛЬНО заполнить форму проектов. -5. Я положу в ветку **khmelov** тот пример, который буду параллельно с вами разрабатывать на факультативах. Полезнее будет - не копипастить, смотрите видео, разбирайтесь, что, почему, где и как сделано. Не копируйте, нужно ВАШЕ решение. Но мы уже и - не совсем зеленые, правда ведь ;). -6. Проверять проекты по итогам третьего модуля я буду с **code review**, и скорее всего быстро не получится, так что за - сроки сдачи можно не волноваться. -7. Планируйте время так, первые три консультации - основной функционал. Последняя консультация - плюшки, рефакторинг, - тесты, красоты. -8. Если будут какие-то моменты - я обновлю это README. Поглядывайте периодически. - -#### _2026 JRU Pantera, Александр Хмелев._ diff --git a/pom.xml b/pom.xml index 78ee59d..0b97e9d 100644 --- a/pom.xml +++ b/pom.xml @@ -4,17 +4,16 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.javarush.khmelov - project-ledzeppelin + com.javarush.chebotarev + project-pantera 1.0-SNAPSHOT - ProjectLedzeppelin + ProjectPantera war UTF-8 21 21 - 5.10.2 @@ -50,11 +49,6 @@ jakarta.servlet.jsp.jstl - - org.projectlombok - lombok - provided - org.junit.jupiter junit-jupiter-api @@ -65,6 +59,22 @@ junit-jupiter-engine test + + org.mockito + mockito-core + test + + + org.mockito + mockito-junit-jupiter + test + + + + com.fasterxml.jackson.core + jackson-databind + 2.15.2 + @@ -75,20 +85,62 @@ maven-war-plugin 3.4.0 + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + + **/*IT.java + + + + org.apache.maven.plugins - maven-compiler-plugin + maven-failsafe-plugin + 3.2.5 + + + integration-test + + integration-test + + + + verify + + verify + + + - - - org.projectlombok - lombok - 1.18.34 - - + + **/*IT.java + + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + prepare-agent + + + + report + verify + + report + + + + - \ No newline at end of file diff --git a/src/main/java/com/javarush/khmelov/cmd/Command.java b/src/main/java/com/javarush/chebotarev/cmd/Command.java similarity index 69% rename from src/main/java/com/javarush/khmelov/cmd/Command.java rename to src/main/java/com/javarush/chebotarev/cmd/Command.java index fd4035b..87ae2f1 100644 --- a/src/main/java/com/javarush/khmelov/cmd/Command.java +++ b/src/main/java/com/javarush/chebotarev/cmd/Command.java @@ -1,23 +1,24 @@ -package com.javarush.khmelov.cmd; +package com.javarush.chebotarev.cmd; +import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import java.util.stream.Collectors; import java.util.stream.Stream; -public interface Command { +public abstract class Command { - default String doGet(HttpServletRequest request) { + public String doGet(HttpServletRequest req, HttpServlet servlet) { return getView(); } - default String doPost(HttpServletRequest request) { + public String doPost(HttpServletRequest req) { return getView(); } - default String getView() { + protected String getView() { String simpleName = this.getClass().getSimpleName(); - return convertCamelCaseToKebabStyle(simpleName); + return "/" + convertCamelCaseToKebabStyle(simpleName); } private static String convertCamelCaseToKebabStyle(String string) { @@ -32,6 +33,4 @@ private static String convertCamelCaseToKebabStyle(String string) { ? snakeName.substring(1) : snakeName; } - - } diff --git a/src/main/java/com/javarush/chebotarev/cmd/ContinueQuest.java b/src/main/java/com/javarush/chebotarev/cmd/ContinueQuest.java new file mode 100644 index 0000000..9662f0a --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/cmd/ContinueQuest.java @@ -0,0 +1,32 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.component.Attribute; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.Utils; +import com.javarush.chebotarev.quest.CurrentQuest; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +@SuppressWarnings("unused") +public class ContinueQuest extends Command { + + @Override + public String doGet(HttpServletRequest req, HttpServlet servlet) { + HttpSession currentSession = req.getSession(); + CurrentQuest currentQuest = Utils.extractAttribute( + currentSession, + Attribute.CURRENT_QUEST, + CurrentQuest.class + ); + String view; + if (!currentQuest.isStarted()) { + view = Go.NEW_QUEST; + } else if (!currentQuest.isDone()) { + view = Go.QUEST; + } else { + view = Go.RESULT; + } + return view; + } +} diff --git a/src/main/java/com/javarush/chebotarev/cmd/Editor.java b/src/main/java/com/javarush/chebotarev/cmd/Editor.java new file mode 100644 index 0000000..ca1a293 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/cmd/Editor.java @@ -0,0 +1,34 @@ +package com.javarush.chebotarev.cmd; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; +import com.javarush.chebotarev.component.QuestService; +import com.javarush.chebotarev.quest.Quest; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; + +import java.io.IOException; + +@SuppressWarnings("unused") +public class Editor extends Command { + + @Override + public String doGet(HttpServletRequest req, HttpServlet servlet) { + return Go.EDITOR; + } + + @Override + public String doPost(HttpServletRequest req) { + try { + req.setCharacterEncoding("UTF-8"); + ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); + Quest quest = mapper.readValue(req.getReader(), Quest.class); + QuestService questService = ObjectRepository.find(QuestService.class); + questService.saveQuest(quest); + } catch (IOException e) { + throw new RuntimeException(e); + } + return Go.ROOT; + } +} diff --git a/src/main/java/com/javarush/chebotarev/cmd/MainMenu.java b/src/main/java/com/javarush/chebotarev/cmd/MainMenu.java new file mode 100644 index 0000000..21aaff6 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/cmd/MainMenu.java @@ -0,0 +1,32 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.component.*; +import com.javarush.chebotarev.quest.QuestMetadata; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +import java.util.List; + +@SuppressWarnings("unused") +public class MainMenu extends Command { + + @Override + public String doGet(HttpServletRequest req, HttpServlet servlet) { + HttpSession currentSession = req.getSession(); + QuestService questService = ObjectRepository.find(QuestService.class); + List availableQuests + = questService.obtainAvailableQuests(servlet.getServletContext()); + currentSession.setAttribute(Attribute.AVAILABLE_QUESTS, availableQuests); + Statistics statistics = Utils.tryExtractAttribute( + currentSession, + Attribute.STATISTICS, + Statistics.class + ); + if (statistics == null) { + statistics = new Statistics(); + currentSession.setAttribute(Attribute.STATISTICS, statistics); + } + return getView(); + } +} diff --git a/src/main/java/com/javarush/chebotarev/cmd/NewQuest.java b/src/main/java/com/javarush/chebotarev/cmd/NewQuest.java new file mode 100644 index 0000000..e3e56e5 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/cmd/NewQuest.java @@ -0,0 +1,42 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.component.*; +import com.javarush.chebotarev.quest.CurrentQuest; +import com.javarush.chebotarev.quest.Quest; +import com.javarush.chebotarev.quest.QuestMetadata; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +import java.util.ArrayList; +import java.util.List; + +@SuppressWarnings("unused") +public class NewQuest extends Command { + + @Override + @SuppressWarnings("unchecked") + public String doGet(HttpServletRequest req, HttpServlet servlet) { + HttpSession currentSession = req.getSession(); + int selectedQuestIndex = getSelectedQuestIndex(req); + List availableQuests = Utils.extractAttribute( + currentSession, + Attribute.AVAILABLE_QUESTS, + ArrayList.class + ); + QuestService questService = ObjectRepository.find(QuestService.class); + QuestMetadata selectedQuest = availableQuests.get(selectedQuestIndex); + Quest quest = questService.loadQuest( + selectedQuest, + servlet.getServletContext() + ); + CurrentQuest currentQuest = new CurrentQuest(quest); + currentSession.setAttribute(Attribute.CURRENT_QUEST, currentQuest); + return getView(); + } + + private int getSelectedQuestIndex(HttpServletRequest req) { + String questIndexString = req.getParameter(Parameter.QUEST_INDEX); + return Integer.parseInt(questIndexString); + } +} diff --git a/src/main/java/com/javarush/chebotarev/cmd/NextStage.java b/src/main/java/com/javarush/chebotarev/cmd/NextStage.java new file mode 100644 index 0000000..5227073 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/cmd/NextStage.java @@ -0,0 +1,45 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.component.*; +import com.javarush.chebotarev.quest.CurrentQuest; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +@SuppressWarnings("unused") +public class NextStage extends Command { + + @Override + public String doGet(HttpServletRequest req, HttpServlet servlet) { + HttpSession currentSession = req.getSession(); + CurrentQuest currentQuest = Utils.extractAttribute( + currentSession, + Attribute.CURRENT_QUEST, + CurrentQuest.class + ); + int nextNodeId = getSelectedNextNodeId(req); + currentQuest.nextStage(nextNodeId); + String view; + if (currentQuest.isDone()) { + view = Go.RESULT; + Statistics statistics = Utils.extractAttribute( + currentSession, + Attribute.STATISTICS, + Statistics.class + ); + if (currentQuest.isVictory()) { + statistics.incVictories(); + } else { + statistics.incDefeats(); + } + } else { + view = Go.QUEST; + } + return view; + } + + private int getSelectedNextNodeId(HttpServletRequest req) { + String nextNodeIdString = req.getParameter(Parameter.NEXT_NODE_ID); + return Integer.parseInt(nextNodeIdString); + } +} diff --git a/src/main/java/com/javarush/chebotarev/cmd/PreviousStage.java b/src/main/java/com/javarush/chebotarev/cmd/PreviousStage.java new file mode 100644 index 0000000..082cc39 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/cmd/PreviousStage.java @@ -0,0 +1,25 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.component.Attribute; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.Utils; +import com.javarush.chebotarev.quest.CurrentQuest; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +@SuppressWarnings("unused") +public class PreviousStage extends Command { + + @Override + public String doGet(HttpServletRequest req, HttpServlet servlet) { + HttpSession currentSession = req.getSession(); + CurrentQuest currentQuest = Utils.extractAttribute( + currentSession, + Attribute.CURRENT_QUEST, + CurrentQuest.class + ); + currentQuest.previousStage(); + return Go.QUEST; + } +} diff --git a/src/main/java/com/javarush/chebotarev/cmd/StartQuest.java b/src/main/java/com/javarush/chebotarev/cmd/StartQuest.java new file mode 100644 index 0000000..428a888 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/cmd/StartQuest.java @@ -0,0 +1,28 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.component.Attribute; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.Utils; +import com.javarush.chebotarev.quest.CurrentQuest; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +@SuppressWarnings("unused") +public class StartQuest extends Command { + + @Override + public String doGet(HttpServletRequest req, HttpServlet servlet) { + HttpSession currentSession = req.getSession(); + CurrentQuest currentQuest = Utils.extractAttribute( + currentSession, + Attribute.CURRENT_QUEST, + CurrentQuest.class + ); + currentQuest.start(); + if (currentQuest.isDone()) { + throw new RuntimeException("Bad quest: first stage is a finish stage"); + } + return Go.QUEST; + } +} diff --git a/src/main/java/com/javarush/chebotarev/component/Attribute.java b/src/main/java/com/javarush/chebotarev/component/Attribute.java new file mode 100644 index 0000000..2c05865 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/component/Attribute.java @@ -0,0 +1,8 @@ +package com.javarush.chebotarev.component; + +public interface Attribute { + + String AVAILABLE_QUESTS = "availableQuests"; + String STATISTICS = "statistics"; + String CURRENT_QUEST = "currentQuest"; +} diff --git a/src/main/java/com/javarush/chebotarev/component/Go.java b/src/main/java/com/javarush/chebotarev/component/Go.java new file mode 100644 index 0000000..0cdef29 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/component/Go.java @@ -0,0 +1,16 @@ +package com.javarush.chebotarev.component; + +public interface Go { + + String INDEX = ""; + String ROOT = "/"; + String MAIN_MENU = "/main-menu"; + String NEW_QUEST = "/new-quest"; + String START_QUEST = "/start-quest"; + String CONTINUE_QUEST = "/continue-quest"; + String QUEST = "/quest"; + String NEXT_STAGE = "/next-stage"; + String PREVIOUS_STAGE = "/previous-stage"; + String RESULT = "/result"; + String EDITOR = "/editor"; +} diff --git a/src/main/java/com/javarush/chebotarev/component/ObjectRepository.java b/src/main/java/com/javarush/chebotarev/component/ObjectRepository.java new file mode 100644 index 0000000..30cabf0 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/component/ObjectRepository.java @@ -0,0 +1,28 @@ +package com.javarush.chebotarev.component; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.ConcurrentHashMap; + +public class ObjectRepository { + + private static final ConcurrentHashMap, Object> objects = new ConcurrentHashMap<>(); + + @SuppressWarnings("unchecked") + public static T find(Class aClass) { + Object object = objects.get(aClass); + if (object == null) { + try { + Constructor constructor = aClass.getConstructor(); + object = constructor.newInstance(); + } catch (NoSuchMethodException + | InvocationTargetException + | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + objects.put(aClass, object); + } + return (T) object; + } +} diff --git a/src/main/java/com/javarush/chebotarev/component/Parameter.java b/src/main/java/com/javarush/chebotarev/component/Parameter.java new file mode 100644 index 0000000..083780a --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/component/Parameter.java @@ -0,0 +1,7 @@ +package com.javarush.chebotarev.component; + +public interface Parameter { + + String QUEST_INDEX = "questIndex"; + String NEXT_NODE_ID = "nextNodeId"; +} diff --git a/src/main/java/com/javarush/chebotarev/component/QuestService.java b/src/main/java/com/javarush/chebotarev/component/QuestService.java new file mode 100644 index 0000000..86f10a4 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/component/QuestService.java @@ -0,0 +1,117 @@ +package com.javarush.chebotarev.component; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.javarush.chebotarev.quest.Quest; +import com.javarush.chebotarev.quest.QuestMetadata; +import jakarta.servlet.ServletContext; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +public class QuestService { + + private final String SERVER_QUESTS_PATH = "/WEB-INF/quests/"; + private final String userQuestsPath; + + public QuestService() { + userQuestsPath = System.getProperty("user.home") + File.separator + "quests"; + File dir = new File(userQuestsPath); + if (!dir.exists()) { + if (!dir.mkdir()) { + throw new RuntimeException("Could not create user quests directory"); + } + } + } + + public String saveQuest(Quest quest) { + String filepath; + File file; + do { + String filename = "quest_" + System.currentTimeMillis() + ".json"; + file = new File(userQuestsPath, filename); + filepath = userQuestsPath + File.separator + filename; + } while (file.exists()); + ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); + try { + mapper.writerWithDefaultPrettyPrinter().writeValue(file, quest); + } catch (IOException e) { + throw new RuntimeException(e); + } + return filepath; + } + + public Quest loadQuest(QuestMetadata questMetadata, ServletContext servletContext) { + Quest quest; + if (questMetadata.isServerQuest()) { + InputStream inputStream = servletContext.getResourceAsStream(questMetadata.getPath()); + quest = loadQuest(inputStream); + try { + inputStream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); + File file = new File(questMetadata.getPath()); + try { + quest = mapper.readValue(file, Quest.class); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return quest; + } + + public Quest loadQuest(InputStream inputStream) { + Quest quest; + ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); + try { + quest = mapper.readValue(inputStream, Quest.class); + } catch (IOException e) { + throw new RuntimeException(e); + } + return quest; + } + + public List obtainAvailableQuests(ServletContext servletContext) { + List availableQuests = new ArrayList<>(); + Set resourcePaths = servletContext.getResourcePaths(SERVER_QUESTS_PATH); + ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); + for (String path : resourcePaths) { + InputStream inputStream = servletContext.getResourceAsStream(path); + Quest quest; + try { + quest = mapper.readValue(inputStream, Quest.class); + inputStream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + QuestMetadata questMetadata = new QuestMetadata( + quest.getTitle(), + path, + true + ); + availableQuests.add(questMetadata); + } + File dir = new File(userQuestsPath); + File[] files = Objects.requireNonNull(dir.listFiles()); + for (File file : files) { + Quest quest; + try { + quest = mapper.readValue(file, Quest.class); + } catch (IOException e) { + throw new RuntimeException(e); + } + QuestMetadata questMetadata = new QuestMetadata(quest.getTitle(), + file.getAbsolutePath(), + false); + availableQuests.add(questMetadata); + } + return availableQuests; + } +} diff --git a/src/main/java/com/javarush/chebotarev/component/Statistics.java b/src/main/java/com/javarush/chebotarev/component/Statistics.java new file mode 100644 index 0000000..d6e2f9f --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/component/Statistics.java @@ -0,0 +1,27 @@ +package com.javarush.chebotarev.component; + +public class Statistics { + + private int victoriesCount = 0; + private int defeatsCount = 0; + + public int getVictoriesCount() { + return victoriesCount; + } + + public int getDefeatsCount() { + return defeatsCount; + } + + public int getGamesCount() { + return (victoriesCount + defeatsCount); + } + + public void incVictories() { + victoriesCount++; + } + + public void incDefeats() { + defeatsCount++; + } +} diff --git a/src/main/java/com/javarush/chebotarev/component/Utils.java b/src/main/java/com/javarush/chebotarev/component/Utils.java new file mode 100644 index 0000000..09d34a1 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/component/Utils.java @@ -0,0 +1,39 @@ +package com.javarush.chebotarev.component; + +import jakarta.servlet.http.HttpSession; + +public class Utils { + + private Utils() { + } + + @SuppressWarnings("unchecked") + public static T tryExtractAttribute(HttpSession currentSession, + String attributeName, + Class attributeClass) { + Object attribute = currentSession.getAttribute(attributeName); + if (attribute != null) { + Class extractedAttributeClass = attribute.getClass(); + if (extractedAttributeClass.equals(attributeClass)) { + return (T) attribute; + } + } + return null; + } + + public static T extractAttribute(HttpSession currentSession, + String attributeName, + Class attributeClass) { + T attribute = tryExtractAttribute( + currentSession, + attributeName, + attributeClass + ); + if (attribute != null) { + return attribute; + } else { + currentSession.invalidate(); + throw new RuntimeException("Session is broken, try one more time"); + } + } +} diff --git a/src/main/java/com/javarush/khmelov/controller/FrontController.java b/src/main/java/com/javarush/chebotarev/controller/FrontController.java similarity index 54% rename from src/main/java/com/javarush/khmelov/controller/FrontController.java rename to src/main/java/com/javarush/chebotarev/controller/FrontController.java index 33242b2..9397506 100644 --- a/src/main/java/com/javarush/khmelov/controller/FrontController.java +++ b/src/main/java/com/javarush/chebotarev/controller/FrontController.java @@ -1,9 +1,8 @@ -package com.javarush.khmelov.controller; +package com.javarush.chebotarev.controller; -import com.javarush.khmelov.cmd.Command; -import com.javarush.khmelov.config.Winter; -import com.javarush.khmelov.entity.Role; -import jakarta.servlet.ServletConfig; +import com.javarush.chebotarev.cmd.Command; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; @@ -12,32 +11,37 @@ import java.io.IOException; -@WebServlet({"", "/home", "/list-user", "/edit-user"}) +@WebServlet({ + Go.INDEX, + Go.MAIN_MENU, + Go.NEW_QUEST, + Go.START_QUEST, + Go.CONTINUE_QUEST, + Go.NEXT_STAGE, + Go.PREVIOUS_STAGE, + Go.EDITOR +}) public class FrontController extends HttpServlet { - private final HttpResolver httpResolver = Winter.find(HttpResolver.class); + private final HttpResolver httpResolver = ObjectRepository.find(HttpResolver.class); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Command command = httpResolver.resolve(req); - String view = command.doGet(req); + String view = command.doGet(req, this); String jsp = getJsp(view); - req.getRequestDispatcher(jsp).forward(req, resp); + req.getRequestDispatcher(jsp) + .forward(req, resp); } @Override - public void init(ServletConfig config) { - config.getServletContext().setAttribute("roles", Role.values()); - } - - private static String getJsp(String view) { - return "/WEB-INF/" + view + ".jsp"; - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { Command command = httpResolver.resolve(req); String redirect = command.doPost(req); resp.sendRedirect(redirect); } + + private static String getJsp(String view) { + return "/WEB-INF" + view + ".jsp"; + } } diff --git a/src/main/java/com/javarush/khmelov/controller/HttpResolver.java b/src/main/java/com/javarush/chebotarev/controller/HttpResolver.java similarity index 55% rename from src/main/java/com/javarush/khmelov/controller/HttpResolver.java rename to src/main/java/com/javarush/chebotarev/controller/HttpResolver.java index 18bb761..29e1ea2 100644 --- a/src/main/java/com/javarush/khmelov/controller/HttpResolver.java +++ b/src/main/java/com/javarush/chebotarev/controller/HttpResolver.java @@ -1,24 +1,27 @@ -package com.javarush.khmelov.controller; +package com.javarush.chebotarev.controller; -import com.javarush.khmelov.cmd.Command; -import com.javarush.khmelov.config.Winter; +import com.javarush.chebotarev.cmd.Command; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; import jakarta.servlet.http.HttpServletRequest; public class HttpResolver { public Command resolve(HttpServletRequest request) { - // /cmd-example + String requestURI = request.getRequestURI(); + requestURI = requestURI.equals("/") + ? Go.MAIN_MENU + : requestURI; + String kebabName = requestURI.split("[?#/]")[1]; + String simpleName = convertKebabStyleToCamelCase(kebabName); + String fullName = Command.class.getPackageName() + "." + simpleName; + Class aClass; try { - String requestURI = request.getRequestURI(); - requestURI = requestURI.equals("/") ? "/start-page" : requestURI; - String kebabName = requestURI.split("[?#/]")[1]; - String simpleName = convertKebabStyleToCamelCase(kebabName); - String fullName = Command.class.getPackageName() + "." + simpleName; - Class aClass = Class.forName(fullName); - return (Command) Winter.find(aClass); + aClass = Class.forName(fullName); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } + return (Command) ObjectRepository.find(aClass); } private String convertKebabStyleToCamelCase(String input) { diff --git a/src/main/java/com/javarush/chebotarev/quest/CurrentQuest.java b/src/main/java/com/javarush/chebotarev/quest/CurrentQuest.java new file mode 100644 index 0000000..5defbab --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/quest/CurrentQuest.java @@ -0,0 +1,91 @@ +package com.javarush.chebotarev.quest; + +import java.util.List; + +public class CurrentQuest { + + private final int CANDLE_COUNT_INIT = 3; + private final Quest quest; + private Node currentNode = null; + private Node previousNode = null; + private int candleCount = CANDLE_COUNT_INIT; + + public CurrentQuest(Quest quest) { + this.quest = quest; + } + + public String getTitle() { + return quest.getTitle(); + } + + public String getPrologue() { + return quest.getPrologue(); + } + + public String getText() { + return currentNode.getText(); + } + + public List