4d2081b369d4253325c78449253cf8b67d412c5e
[idea/community.git] / python / educational / course-creator / src / com / jetbrains / edu / coursecreator / CCProjectService.java
1 /*
2  * Copyright 2000-2013 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.jetbrains.edu.coursecreator;
17
18 import com.intellij.openapi.actionSystem.AnActionEvent;
19 import com.intellij.openapi.components.PersistentStateComponent;
20 import com.intellij.openapi.components.ServiceManager;
21 import com.intellij.openapi.components.State;
22 import com.intellij.openapi.components.Storage;
23 import com.intellij.openapi.editor.Document;
24 import com.intellij.openapi.editor.Editor;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.util.io.FileUtil;
27 import com.intellij.openapi.util.io.FileUtilRt;
28 import com.intellij.openapi.vfs.VirtualFile;
29 import com.intellij.ui.JBColor;
30 import com.intellij.util.xmlb.XmlSerializerUtil;
31 import com.jetbrains.edu.EduAnswerPlaceholderPainter;
32 import com.jetbrains.edu.EduDocumentListener;
33 import com.jetbrains.edu.EduNames;
34 import com.jetbrains.edu.EduUtils;
35 import com.jetbrains.edu.courseFormat.*;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
38
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Map;
42
43 @State(name = "CCProjectService",
44        storages = {
45          @Storage(file = "$PROJECT_CONFIG_DIR$/course_service.xml")
46        }
47 )
48 public class CCProjectService implements PersistentStateComponent<CCProjectService> {
49   private Course myCourse;
50
51   private static final Map<Document, EduDocumentListener> myDocumentListeners = new HashMap<Document, EduDocumentListener>();
52
53   @Nullable
54   public TaskFile getTaskFile(@NotNull final VirtualFile virtualFile) {
55     VirtualFile taskDir = virtualFile.getParent();
56     if (taskDir == null) {
57       return null;
58     }
59     String taskDirName = taskDir.getName();
60     if (!taskDirName.contains(EduNames.TASK)) {
61       return null;
62     }
63     VirtualFile lessonDir = taskDir.getParent();
64     if (lessonDir == null) {
65       return null;
66     }
67     String lessonDirName = lessonDir.getName();
68     if (!lessonDirName.contains(EduNames.LESSON)) {
69       return null;
70     }
71     Lesson lesson = myCourse.getLesson(lessonDirName);
72     if (lesson == null) {
73       return null;
74     }
75     Task task = lesson.getTask(taskDir.getName());
76     if (task == null) {
77       return null;
78     }
79     String fileName = getRealTaskFileName(virtualFile.getName());
80     return task.getTaskFile(fileName);
81   }
82
83   public void drawAnswerPlaceholders(@NotNull final VirtualFile virtualFile, @NotNull final Editor editor) {
84     TaskFile taskFile = getTaskFile(virtualFile);
85     if (taskFile == null) {
86       return;
87     }
88     List<AnswerPlaceholder> answerPlaceholders = taskFile.getAnswerPlaceholders();
89     for (AnswerPlaceholder answerPlaceholder : answerPlaceholders) {
90       EduAnswerPlaceholderPainter.drawAnswerPlaceholder(editor, answerPlaceholder, false, JBColor.BLUE);
91     }
92   }
93
94   public static void addDocumentListener(Document document, EduDocumentListener listener) {
95     myDocumentListeners.put(document, listener);
96   }
97
98   public static EduDocumentListener getListener(Document document) {
99     return myDocumentListeners.get(document);
100   }
101
102   public static void removeListener(Document document) {
103     myDocumentListeners.remove(document);
104   }
105
106   public boolean isTaskFile(VirtualFile file) {
107     if (myCourse == null || file == null) {
108       return false;
109     }
110     VirtualFile taskDir = file.getParent();
111     if (taskDir != null) {
112       String taskDirName = taskDir.getName();
113       if (taskDirName.contains(EduNames.TASK)) {
114         VirtualFile lessonDir = taskDir.getParent();
115         if (lessonDir != null) {
116           String lessonDirName = lessonDir.getName();
117           int lessonIndex = EduUtils.getIndex(lessonDirName, EduNames.LESSON);
118           List<Lesson> lessons = myCourse.getLessons();
119           if (!EduUtils.indexIsValid(lessonIndex, lessons)) {
120             return false;
121           }
122           Lesson lesson = lessons.get(lessonIndex);
123           int taskIndex = EduUtils.getIndex(taskDirName, EduNames.TASK);
124           List<Task> tasks = lesson.getTaskList();
125           if (!EduUtils.indexIsValid(taskIndex, tasks)) {
126             return false;
127           }
128           Task task = tasks.get(taskIndex);
129           return task.isTaskFile(file.getName());
130         }
131       }
132     }
133     return false;
134   }
135
136   @Nullable
137   public static String getRealTaskFileName(String name) {
138     String nameWithoutExtension = FileUtil.getNameWithoutExtension(name);
139     String extension = FileUtilRt.getExtension(name);
140     if (!nameWithoutExtension.endsWith(".answer")) {
141       return null;
142     }
143     int nameEnd = name.indexOf(".answer");
144     return name.substring(0, nameEnd) + "." + extension;
145   }
146
147   public static boolean setCCActionAvailable(@NotNull AnActionEvent e) {
148     final Project project = e.getProject();
149     if (project == null) {
150       return false;
151     }
152     if (getInstance(project).getCourse() == null) {
153       EduUtils.enableAction(e, false);
154       return false;
155     }
156     EduUtils.enableAction(e, true);
157     return true;
158   }
159
160   public Course getCourse() {
161     return myCourse;
162   }
163
164   public void setCourse(@NotNull final Course course) {
165     myCourse = course;
166   }
167
168   @Override
169   public CCProjectService getState() {
170     return this;
171   }
172
173   @Override
174   public void loadState(CCProjectService state) {
175     XmlSerializerUtil.copyBean(state, this);
176     myCourse.initCourse(true);
177   }
178
179   public static CCProjectService getInstance(@NotNull Project project) {
180     return ServiceManager.getService(project, CCProjectService.class);
181   }
182
183 }