moved everything python dependent to language part of plugin
[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.ide.projectView.ProjectView;
19 import com.intellij.openapi.actionSystem.AnActionEvent;
20 import com.intellij.openapi.components.PersistentStateComponent;
21 import com.intellij.openapi.components.ServiceManager;
22 import com.intellij.openapi.components.State;
23 import com.intellij.openapi.components.Storage;
24 import com.intellij.openapi.diagnostic.Logger;
25 import com.intellij.openapi.editor.Document;
26 import com.intellij.openapi.editor.Editor;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.openapi.util.io.FileUtil;
29 import com.intellij.openapi.util.io.FileUtilRt;
30 import com.intellij.openapi.vfs.VirtualFile;
31 import com.intellij.openapi.vfs.VirtualFileManager;
32 import com.intellij.util.xmlb.XmlSerializer;
33 import com.jetbrains.edu.coursecreator.format.*;
34 import org.jdom.Element;
35 import org.jetbrains.annotations.NotNull;
36 import org.jetbrains.annotations.Nullable;
37
38 import java.io.File;
39 import java.util.Collection;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43
44 @State(name = "CCProjectService",
45        storages = {
46          @Storage(file = "$PROJECT_CONFIG_DIR$/course_service.xml")
47        }
48 )
49 public class CCProjectService implements PersistentStateComponent<Element> {
50
51   private static final Logger LOG = Logger.getInstance(CCProjectService.class.getName());
52   private Course myCourse;
53   public static final String COURSE_ELEMENT = "course";
54   private static final Map<Document, CCDocumentListener> myDocumentListeners = new HashMap<Document, CCDocumentListener>();
55
56   public void setCourse(@NotNull final Course course) {
57     myCourse = course;
58   }
59
60   public Course getCourse() {
61     return myCourse;
62   }
63
64   @Override
65   public Element getState() {
66     final Element el = new Element("CCProjectService");
67     if (myCourse != null) {
68       Element courseElement = new Element(COURSE_ELEMENT);
69       XmlSerializer.serializeInto(myCourse, courseElement);
70       el.addContent(courseElement);
71     }
72     return el;
73   }
74
75   @Override
76   public void loadState(Element el) {
77     myCourse = XmlSerializer.deserialize(el.getChild(COURSE_ELEMENT), Course.class);
78     if (myCourse != null) {
79       myCourse.init();
80     }
81   }
82
83   public static CCProjectService getInstance(@NotNull Project project) {
84     return ServiceManager.getService(project, CCProjectService.class);
85   }
86
87   public static void deleteProjectFile(File file, @NotNull final Project project) {
88     if (!file.delete()) {
89       LOG.info("Failed to delete file " + file.getPath());
90     }
91     VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
92     ProjectView.getInstance(project).refresh();
93   }
94
95   @Nullable
96   public TaskFile getTaskFile(@NotNull final VirtualFile virtualFile) {
97     VirtualFile taskDir = virtualFile.getParent();
98     if (taskDir == null) {
99       return null;
100     }
101     String taskDirName = taskDir.getName();
102     if (!taskDirName.contains("task")) {
103       return null;
104     }
105     VirtualFile lessonDir = taskDir.getParent();
106     if (lessonDir == null) {
107       return null;
108     }
109     String lessonDirName = lessonDir.getName();
110     if (!lessonDirName.contains("lesson")) {
111       return null;
112     }
113     Lesson lesson = myCourse.getLessonsMap().get(lessonDirName);
114     if (lesson == null) {
115       return null;
116     }
117     Task task = lesson.getTask(taskDirName);
118     if (task == null) {
119       return null;
120     }
121     return task.getTaskFile(virtualFile.getName());
122   }
123
124   public void drawTaskWindows(@NotNull final VirtualFile virtualFile, @NotNull final Editor editor) {
125     TaskFile taskFile = getTaskFile(virtualFile);
126     if (taskFile == null) {
127       return;
128     }
129     List<AnswerPlaceholder> answerPlaceholders = taskFile.getTaskWindows();
130     for (AnswerPlaceholder answerPlaceholder : answerPlaceholders) {
131       answerPlaceholder.drawHighlighter(editor, false);
132     }
133   }
134
135   public static void addDocumentListener(Document document, CCDocumentListener listener) {
136     myDocumentListeners.put(document, listener);
137   }
138
139   public static CCDocumentListener getListener(Document document) {
140     return myDocumentListeners.get(document);
141   }
142
143   public static void removeListener(Document document) {
144     myDocumentListeners.remove(document);
145   }
146
147   public static boolean indexIsValid(int index, Collection collection) {
148     int size = collection.size();
149     return index >= 0 && index < size;
150   }
151
152   public boolean isTaskFile(VirtualFile file) {
153     if (myCourse == null || file == null) {
154       return false;
155     }
156     VirtualFile taskDir = file.getParent();
157     if (taskDir != null) {
158       String taskDirName = taskDir.getName();
159       if (taskDirName.contains("task")) {
160         VirtualFile lessonDir = taskDir.getParent();
161         if (lessonDir != null) {
162           String lessonDirName = lessonDir.getName();
163           int lessonIndex = getIndex(lessonDirName, "lesson");
164           List<Lesson> lessons = myCourse.getLessons();
165           if (!indexIsValid(lessonIndex, lessons)) {
166             return false;
167           }
168           Lesson lesson = lessons.get(lessonIndex);
169           int taskIndex = getIndex(taskDirName, "task");
170           List<Task> tasks = lesson.getTaskList();
171           if (!indexIsValid(taskIndex, tasks)) {
172             return false;
173           }
174           Task task = tasks.get(taskIndex);
175           return task.isTaskFile(file.getName());
176         }
177       }
178     }
179     return false;
180   }
181
182   public static int getIndex(@NotNull final String fullName, @NotNull final String logicalName) {
183     if (!fullName.contains(logicalName)) {
184       throw new IllegalArgumentException();
185     }
186     return Integer.parseInt(fullName.substring(logicalName.length())) - 1;
187   }
188   public static String getRealTaskFileName(String name) {
189     String nameWithoutExtension = FileUtil.getNameWithoutExtension(name);
190     String extension = FileUtilRt.getExtension(name);
191     if (!nameWithoutExtension.endsWith(".answer")) {
192       return null;
193     }
194     int nameEnd = name.indexOf(".answer");
195     return name.substring(0, nameEnd) + "." + extension;
196   }
197
198   public static boolean setCCActionAvailable(@NotNull AnActionEvent e) {
199     final Project project = e.getProject();
200     if (project == null) {
201       return false;
202     }
203     if (getInstance(project).getCourse() == null) {
204       CCUtils.enableAction(e, false);
205       return false;
206     }
207     CCUtils.enableAction(e, true);
208     return true;
209   }
210 }