1 package com.jetbrains.edu.learning.courseFormat;
3 import com.google.gson.annotations.Expose;
4 import com.google.gson.annotations.SerializedName;
5 import com.intellij.openapi.editor.Document;
6 import com.intellij.openapi.fileEditor.FileDocumentManager;
7 import com.intellij.openapi.project.Project;
8 import com.intellij.openapi.util.text.StringUtil;
9 import com.intellij.openapi.vfs.VirtualFile;
10 import com.intellij.util.xmlb.XmlSerializer;
11 import com.intellij.util.xmlb.annotations.Transient;
12 import com.jetbrains.edu.learning.StudyUtils;
13 import com.jetbrains.edu.learning.core.EduNames;
14 import com.jetbrains.edu.learning.stepic.EduStepicConnector;
15 import org.jdom.Element;
16 import org.jetbrains.annotations.NotNull;
17 import org.jetbrains.annotations.Nullable;
19 import java.util.Date;
20 import java.util.HashMap;
24 * Implementation of task which contains task files, tests, input file for tests
26 public class Task implements StudyItem {
27 @Expose private String name;
29 // index is visible to user number of task from 1 to task number
31 private StudyStatus myStatus = StudyStatus.Unchecked;
33 @SerializedName("stepic_id")
34 @Expose private int myStepId;
36 @SerializedName("task_files")
37 @Expose public Map<String, TaskFile> taskFiles = new HashMap<>();
40 private Map<String, String> testsText = new HashMap<>();
42 @Transient private Lesson myLesson;
43 @Expose @SerializedName("update_date") private Date myUpdateDate;
45 private int myActiveSubtaskIndex = 0;
46 @Expose private int mySubtaskNum = 1;
50 public Task(@NotNull final String name) {
55 * Initializes state of task file
57 * @param lesson lesson which task belongs to
59 public void initTask(final Lesson lesson, boolean isRestarted) {
61 if (!isRestarted) myStatus = StudyStatus.Unchecked;
62 for (TaskFile taskFile : getTaskFiles().values()) {
63 taskFile.initTaskFile(this, isRestarted);
67 public String getName() {
71 public void setName(String name) {
75 public String getText() {
79 public void setText(final String text) {
83 public int getIndex() {
87 public void setIndex(int index) {
91 public Map<String, String> getTestsText() {
95 public void addTestsTexts(String name, String text) {
96 testsText.put(name, text);
99 public Map<String, TaskFile> getTaskFiles() {
104 public TaskFile getTaskFile(final String name) {
105 return name != null ? taskFiles.get(name) : null;
108 public boolean isTaskFile(@NotNull final String fileName) {
109 return taskFiles.get(fileName) != null;
112 public void addTaskFile(@NotNull final String name, int index) {
113 TaskFile taskFile = new TaskFile();
114 taskFile.setIndex(index);
115 taskFile.setTask(this);
116 taskFile.name = name;
117 taskFiles.put(name, taskFile);
120 public void addTaskFile(@NotNull final TaskFile taskFile) {
121 taskFiles.put(taskFile.name, taskFile);
125 public TaskFile getFile(@NotNull final String fileName) {
126 return taskFiles.get(fileName);
130 public Lesson getLesson() {
135 public void setLesson(Lesson lesson) {
140 public VirtualFile getTaskDir(@NotNull final Project project) {
141 String lessonDirName = EduNames.LESSON + String.valueOf(myLesson.getIndex());
142 String taskDirName = EduNames.TASK + String.valueOf(myIndex);
143 VirtualFile courseDir = project.getBaseDir();
144 if (courseDir != null) {
145 VirtualFile lessonDir = courseDir.findChild(lessonDirName);
146 if (lessonDir != null) {
147 return lessonDir.findChild(taskDirName);
154 public String getTaskText(@NotNull final Project project) {
155 if (!StringUtil.isEmptyOrSpaces(text)) return text;
156 final VirtualFile taskDir = getTaskDir(project);
157 if (taskDir != null) {
158 final VirtualFile file = StudyUtils.findTaskDescriptionVirtualFile(taskDir);
159 if (file == null) return "";
160 final Document document = FileDocumentManager.getInstance().getDocument(file);
161 if (document != null) {
162 return document.getImmutableCharSequence().toString();
170 public String getTestsText(@NotNull final Project project) {
171 final VirtualFile taskDir = getTaskDir(project);
172 if (taskDir != null) {
173 final VirtualFile file = taskDir.findChild(EduNames.TESTS_FILE);
174 if (file == null) return "";
175 final Document document = FileDocumentManager.getInstance().getDocument(file);
176 if (document != null) {
177 return document.getImmutableCharSequence().toString();
185 public boolean equals(Object o) {
186 if (this == o) return true;
187 if (o == null || getClass() != o.getClass()) return false;
191 if (myIndex != task.myIndex) return false;
192 if (name != null ? !name.equals(task.name) : task.name != null) return false;
193 if (taskFiles != null ? !taskFiles.equals(task.taskFiles) : task.taskFiles != null) return false;
194 if (text != null ? !text.equals(task.text) : task.text != null) return false;
195 if (testsText != null ? !testsText.equals(task.testsText) : task.testsText != null) return false;
201 public int hashCode() {
202 int result = name != null ? name.hashCode() : 0;
203 result = 31 * result + myIndex;
204 result = 31 * result + (taskFiles != null ? taskFiles.hashCode() : 0);
205 result = 31 * result + (text != null ? text.hashCode() : 0);
206 result = 31 * result + (testsText != null ? testsText.hashCode() : 0);
210 public void setStepId(int stepId) {
214 public int getStepId() {
218 public StudyStatus getStatus() {
222 public void setStatus(StudyStatus status) {
224 for (TaskFile taskFile : taskFiles.values()) {
225 for (AnswerPlaceholder placeholder : taskFile.getActivePlaceholders()) {
226 placeholder.setStatus(status);
232 Element element = XmlSerializer.serialize(this);
233 Task copy = XmlSerializer.deserialize(element, Task.class);
237 copy.initTask(null, true);
241 public void setUpdateDate(Date date) {
245 public Date getUpdateDate() {
249 public boolean isUpToDate() {
250 if (getStepId() == 0) return true;
251 final Date date = EduStepicConnector.getTaskUpdateDate(getStepId());
252 if (date == null) return true;
253 if (myUpdateDate == null) return false;
254 return !date.after(myUpdateDate);
257 public int getActiveSubtaskIndex() {
258 return myActiveSubtaskIndex;
261 public void setActiveSubtaskIndex(int activeSubtaskIndex) {
262 myActiveSubtaskIndex = activeSubtaskIndex;
265 public int getSubtaskNum() {
269 public void setSubtaskNum(int subtaskNum) {
270 mySubtaskNum = subtaskNum;