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 myActiveStepIndex = 0;
49 public Task(@NotNull final String name) {
54 * Initializes state of task file
56 * @param lesson lesson which task belongs to
58 public void initTask(final Lesson lesson, boolean isRestarted) {
60 if (!isRestarted) myStatus = StudyStatus.Unchecked;
61 for (TaskFile taskFile : getTaskFiles().values()) {
62 taskFile.initTaskFile(this, isRestarted);
66 public String getName() {
70 public void setName(String name) {
74 public String getText() {
78 public void setText(final String text) {
82 public int getIndex() {
86 public void setIndex(int index) {
90 public Map<String, String> getTestsText() {
94 public void addTestsTexts(String name, String text) {
95 testsText.put(name, text);
98 public Map<String, TaskFile> getTaskFiles() {
103 public TaskFile getTaskFile(final String name) {
104 return name != null ? taskFiles.get(name) : null;
107 public boolean isTaskFile(@NotNull final String fileName) {
108 return taskFiles.get(fileName) != null;
111 public void addTaskFile(@NotNull final String name, int index) {
112 TaskFile taskFile = new TaskFile();
113 taskFile.setIndex(index);
114 taskFile.setTask(this);
115 taskFile.name = name;
116 taskFiles.put(name, taskFile);
119 public void addTaskFile(@NotNull final TaskFile taskFile) {
120 taskFiles.put(taskFile.name, taskFile);
124 public TaskFile getFile(@NotNull final String fileName) {
125 return taskFiles.get(fileName);
129 public Lesson getLesson() {
134 public void setLesson(Lesson lesson) {
139 public VirtualFile getTaskDir(@NotNull final Project project) {
140 String lessonDirName = EduNames.LESSON + String.valueOf(myLesson.getIndex());
141 String taskDirName = EduNames.TASK + String.valueOf(myIndex);
142 VirtualFile courseDir = project.getBaseDir();
143 if (courseDir != null) {
144 VirtualFile lessonDir = courseDir.findChild(lessonDirName);
145 if (lessonDir != null) {
146 return lessonDir.findChild(taskDirName);
153 public String getTaskText(@NotNull final Project project) {
154 if (!StringUtil.isEmptyOrSpaces(text)) return text;
155 final VirtualFile taskDir = getTaskDir(project);
156 if (taskDir != null) {
157 final VirtualFile file = StudyUtils.findTaskDescriptionVirtualFile(taskDir);
158 if (file == null) return "";
159 final Document document = FileDocumentManager.getInstance().getDocument(file);
160 if (document != null) {
161 return document.getImmutableCharSequence().toString();
169 public String getTestsText(@NotNull final Project project) {
170 final VirtualFile taskDir = getTaskDir(project);
171 if (taskDir != null) {
172 final VirtualFile file = taskDir.findChild(EduNames.TESTS_FILE);
173 if (file == null) return "";
174 final Document document = FileDocumentManager.getInstance().getDocument(file);
175 if (document != null) {
176 return document.getImmutableCharSequence().toString();
184 public boolean equals(Object o) {
185 if (this == o) return true;
186 if (o == null || getClass() != o.getClass()) return false;
190 if (myIndex != task.myIndex) return false;
191 if (name != null ? !name.equals(task.name) : task.name != null) return false;
192 if (taskFiles != null ? !taskFiles.equals(task.taskFiles) : task.taskFiles != null) return false;
193 if (text != null ? !text.equals(task.text) : task.text != null) return false;
194 if (testsText != null ? !testsText.equals(task.testsText) : task.testsText != null) return false;
200 public int hashCode() {
201 int result = name != null ? name.hashCode() : 0;
202 result = 31 * result + myIndex;
203 result = 31 * result + (taskFiles != null ? taskFiles.hashCode() : 0);
204 result = 31 * result + (text != null ? text.hashCode() : 0);
205 result = 31 * result + (testsText != null ? testsText.hashCode() : 0);
209 public void setStepId(int stepId) {
213 public int getStepId() {
217 public StudyStatus getStatus() {
221 public void setStatus(StudyStatus status) {
223 for (TaskFile taskFile : taskFiles.values()) {
224 for (AnswerPlaceholder placeholder : taskFile.getActivePlaceholders()) {
225 placeholder.setStatus(status);
231 Element element = XmlSerializer.serialize(this);
232 Task copy = XmlSerializer.deserialize(element, Task.class);
236 copy.initTask(null, true);
240 public void setUpdateDate(Date date) {
244 public Date getUpdateDate() {
248 public boolean isUpToDate() {
249 if (getStepId() == 0) return true;
250 final Date date = EduStepicConnector.getTaskUpdateDate(getStepId());
251 if (date == null) return true;
252 if (myUpdateDate == null) return false;
253 return !date.after(myUpdateDate);
256 public int getActiveStepIndex() {
257 return myActiveStepIndex;
260 public void setActiveStepIndex(int activeStepIndex) {
261 myActiveStepIndex = activeStepIndex;