001: package nz.ac.massey.take.takeep.editor;
002:
003: import java.io.File;
004: import java.io.Reader;
005: import java.io.StringReader;
006: import java.net.MalformedURLException;
007: import java.net.URL;
008: import java.net.URLClassLoader;
009: import java.util.HashMap;
010: import java.util.LinkedList;
011: import java.util.List;
012:
013: import nz.ac.massey.take.takeep.actionsSets.compileActions.TakeCompileToClasses;
014: import nz.ac.massey.take.takeep.actionsSets.compileActions.TakeCompileToInterfaces;
015: import nz.ac.massey.take.takeep.actionsSets.panels.TakeCompileWizardPanel;
016: import nz.ac.massey.take.takeep.actionsSets.verifyActions.TakeRunVerifiers;
017: import nz.ac.massey.take.takeep.editor.TakeSourceViewerConfiguration.TAKE_TOKENS;
018: import nz.ac.massey.take.takeep.editor.tokens.TakePartitionScanner.TAKE_PARTITIONS;
019: import nz.ac.massey.take.takeep.outline.TakeOutline;
020: import nz.org.take.nscript.Parser;
021: import nz.org.take.nscript.ScriptException;
022:
023: import org.eclipse.core.resources.IFile;
024: import org.eclipse.core.resources.IMarker;
025: import org.eclipse.core.resources.IProject;
026: import org.eclipse.core.resources.IResource;
027: import org.eclipse.core.resources.ResourcesPlugin;
028: import org.eclipse.core.runtime.CoreException;
029: import org.eclipse.core.runtime.IPath;
030: import org.eclipse.core.runtime.IProgressMonitor;
031: import org.eclipse.core.runtime.IStatus;
032: import org.eclipse.core.runtime.Platform;
033: import org.eclipse.core.runtime.Status;
034: import org.eclipse.core.runtime.jobs.Job;
035: import org.eclipse.jdt.core.IClasspathEntry;
036: import org.eclipse.jdt.core.IJavaProject;
037: import org.eclipse.jdt.core.JavaCore;
038: import org.eclipse.jdt.core.JavaModelException;
039: import org.eclipse.jface.action.IMenuManager;
040: import org.eclipse.jface.action.MenuManager;
041: import org.eclipse.jface.text.BadLocationException;
042: import org.eclipse.jface.text.DocumentEvent;
043: import org.eclipse.jface.text.IDocumentListener;
044: import org.eclipse.jface.text.IRegion;
045: import org.eclipse.jface.text.Position;
046: import org.eclipse.jface.text.source.Annotation;
047: import org.eclipse.jface.text.source.AnnotationRulerColumn;
048: import org.eclipse.jface.text.source.CompositeRuler;
049: import org.eclipse.jface.text.source.IVerticalRuler;
050: import org.eclipse.swt.SWT;
051: import org.eclipse.swt.graphics.RGB;
052: import org.eclipse.ui.IEditorInput;
053: import org.eclipse.ui.IWorkbenchPage;
054: import org.eclipse.ui.editors.text.TextEditor;
055: import org.eclipse.ui.part.FileEditorInput;
056: import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
057: import org.eclipse.ui.texteditor.IElementStateListener;
058: import org.eclipse.ui.texteditor.ITextEditorActionConstants;
059: import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
060: import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
061:
062: public class TakeEditor extends TextEditor {
063:
064: private TakeOutline fOutlinePage = null;
065:
066: @Override
067: public Object getAdapter(Class adapter) {
068: if (adapter.equals(IContentOutlinePage.class)) {
069: if (this .fOutlinePage == null) {
070: this .fOutlinePage = new TakeOutline(this );
071: }
072: return this .fOutlinePage;
073: }
074: return super .getAdapter(adapter);
075: }
076:
077: public TakeEditor() {
078: super ();
079: DesignManager cm = new DesignManager();
080: cm.addColor(TAKE_PARTITIONS.TAKE_COMMENT.name(), new RGB(63,
081: 127, 95));
082:
083: cm.addColor(TAKE_PARTITIONS.TAKE_GLOBAL_ANNOTATION.name(),
084: new RGB(128, 128, 128));
085: cm.addStyle(TAKE_PARTITIONS.TAKE_GLOBAL_ANNOTATION.name(),
086: SWT.ITALIC);
087:
088: cm.addColor(TAKE_TOKENS.TAKE_STRING_LITERAL.name(), new RGB(0,
089: 0, 192));
090:
091: cm.addColor(TAKE_TOKENS.TAKE_KEYWORD.name(),
092: new RGB(127, 0, 85));
093: cm.addStyle(TAKE_TOKENS.TAKE_KEYWORD.name(), SWT.BOLD);
094:
095: cm.addColor(TAKE_PARTITIONS.TAKE_LOCAL_ANNOTATION.name(),
096: new RGB(0, 0, 192));
097:
098: this .setContentDescription("Take Editor");
099: this
100: .setSourceViewerConfiguration(new TakeSourceViewerConfiguration(
101: this , cm));
102: this .setDocumentProvider(new TakeDocumentProvider());
103:
104: getPreferenceStore()
105: .setValue(
106: AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER,
107: true);
108:
109: this .getDocumentProvider().addElementStateListener(
110: new IElementStateListener() {
111:
112: @Override
113: public void elementContentAboutToBeReplaced(
114: Object element) {
115: }
116:
117: @Override
118: public void elementContentReplaced(Object element) {
119: }
120:
121: @Override
122: public void elementDeleted(Object element) {
123: }
124:
125: @Override
126: public void elementDirtyStateChanged(
127: Object element, boolean isDirty) {
128: if (!isDirty) {
129: runVerifier();
130: }
131: }
132:
133: @Override
134: public void elementMoved(Object originalElement,
135: Object movedElement) {
136:
137: }
138: });
139:
140: }
141:
142: public static URLClassLoader getProjectClassLoader(
143: IJavaProject project) {
144: List<URL> pathElements = getProjectClassPathURLs(project);
145: URL urlPaths[] = pathElements.toArray(new URL[pathElements
146: .size()]);
147:
148: return new URLClassLoader(urlPaths);
149: }
150:
151: private static URL getRawLocationURL(IPath simplePath)
152: throws MalformedURLException {
153: File file = getRawLocationFile(simplePath);
154: return file.toURI().toURL();
155: }
156:
157: private static File getRawLocationFile(IPath simplePath) {
158: org.eclipse.core.resources.IResource resource = ResourcesPlugin
159: .getWorkspace().getRoot().findMember(simplePath);
160: File file = null;
161: if (resource != null) {
162: file = resource.getRawLocation().toFile();
163: } else {
164: file = simplePath.toFile();
165: }
166: return file;
167: }
168:
169: public static List<URL> getProjectClassPathURLs(IJavaProject project) {
170: List<URL> pathElements = new LinkedList<URL>();
171: try {
172: IClasspathEntry[] paths = project
173: .getResolvedClasspath(true);
174: if (paths != null) {
175:
176: for (int i = 0; i < paths.length; i++) {
177: IClasspathEntry path = paths[i];
178: if (path.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
179: URL url = getRawLocationURL(path.getPath());
180: pathElements.add(url);
181: }
182: }
183: }
184: IPath location = getProjectLocation(project.getProject());
185: IPath outputPath = location.append(project
186: .getOutputLocation().removeFirstSegments(1));
187: pathElements.add(outputPath.toFile().toURL());
188:
189: // also add classpath of required projects
190: String[] names = project.getRequiredProjectNames();
191: for (int i = 0; i < names.length; i++) {
192: String projectName = names[i];
193: IProject reqProject = project.getProject()
194: .getWorkspace().getRoot().getProject(
195: projectName);
196: if (reqProject != null) {
197: IJavaProject reqJavaProject = JavaCore
198: .create(reqProject);
199: pathElements
200: .addAll(getProjectClassPathURLs(reqJavaProject));
201: }
202: }
203: } catch (JavaModelException e) {
204: e.printStackTrace();
205: } catch (MalformedURLException e) {
206: e.printStackTrace();
207: }
208: return pathElements;
209: }
210:
211: public static IPath getProjectLocation(IProject project) {
212: if (project.getRawLocation() == null) {
213: return project.getLocation();
214: } else {
215: return project.getRawLocation();
216: }
217: }
218:
219: private HashMap<Annotation, IMarker> anno = new HashMap<Annotation, IMarker>();
220:
221: public void runVerifier() {
222:
223: IWorkbenchPage workbench = TakeCompileWizardPanel
224: .getWorkbench();
225: IProject project = TakeCompileWizardPanel
226: .getProjectFromWorkbench(workbench);
227: ClassLoader cl = getProjectClassLoader(JavaCore.create(project));
228:
229: final ResourceMarkerAnnotationModel annotationModel = (ResourceMarkerAnnotationModel) getDocumentProvider()
230: .getAnnotationModel(getEditorInput());
231:
232: for (Annotation a : this .anno.keySet()) {
233: annotationModel.removeAnnotation(a);
234: }
235: final IFile file = ((FileEditorInput) this .getEditorInput())
236: .getFile();
237: try {
238: file.deleteMarkers(IMarker.PROBLEM, true,
239: IResource.DEPTH_INFINITE);
240: } catch (CoreException e1) {
241: // TODO Auto-generated catch block
242: e1.printStackTrace();
243: return;
244: }
245: this .anno.clear();
246:
247: final Parser p = new Parser();
248: p.setClassLoader(cl);
249: final Reader script;
250: script = new StringReader(this .getDocumentProvider()
251: .getDocument(this .getEditorInput()).get());
252:
253: try {
254: List<ScriptException> check = p.check(script);
255:
256: for (ScriptException se : check) {
257:
258: IMarker marker;
259:
260: marker = file.createMarker(IMarker.PROBLEM);
261:
262: marker.setAttribute(IMarker.MESSAGE, se.getMessage());
263: marker.setAttribute(IMarker.LOCATION, se.getLine());
264:
265: Annotation annotation = new Annotation(
266: "org.eclipse.ui.workbench.texteditor.error",
267: false, se.getMessage());
268: anno.put(annotation, marker);
269: IRegion lineInformation = getSourceViewer()
270: .getDocument().getLineInformation(
271: se.getLine() - 1);
272: annotationModel.addAnnotation(annotation, new Position(
273: lineInformation.getOffset(), lineInformation
274: .getLength()));
275:
276: }
277: } catch (Exception e) {
278: // TODO Auto-generated catch block
279: e.printStackTrace();
280: }
281:
282: }
283:
284: @Override
285: protected IVerticalRuler createVerticalRuler() {
286: CompositeRuler ruler = new CompositeRuler();
287: ruler.addDecorator(0, new AnnotationRulerColumn(
288: VERTICAL_RULER_WIDTH));
289: return ruler;
290: }
291:
292: @Override
293: protected void editorSaved() {
294: // TODO Auto-generated method stub
295: super .editorSaved();
296:
297: if (this .fOutlinePage != null)
298: this .fOutlinePage.update();
299: }
300:
301: @Override
302: protected void createActions() {
303: // TODO Auto-generated method stub
304: super .createActions();
305:
306: }
307:
308: @Override
309: protected void editorContextMenuAboutToShow(IMenuManager menu) {
310: // TODO Auto-generated method stub
311: super .editorContextMenuAboutToShow(menu);
312:
313: this .addGroup(menu, ITextEditorActionConstants.GROUP_EDIT,
314: "Take");
315:
316: MenuManager compileMenu = new MenuManager("Take Compile");
317: compileMenu.add(new TakeCompileToClasses());
318: compileMenu.add(new TakeCompileToInterfaces());
319: menu.appendToGroup("Take", compileMenu);
320:
321: MenuManager verifyMenu = new MenuManager("Take Verify");
322: verifyMenu.add(new TakeRunVerifiers());
323: menu.appendToGroup("Take", verifyMenu);
324:
325: }
326:
327: @Override
328: protected void doSetInput(final IEditorInput input)
329: throws CoreException {
330: super .doSetInput(input);
331:
332: this .getDocumentProvider().getDocument(input)
333: .addDocumentListener(new IDocumentListener() {
334:
335: private long lastRun = 0;
336:
337: @Override
338: public void documentAboutToBeChanged(
339: DocumentEvent event) {
340:
341: }
342:
343: @Override
344: public void documentChanged(DocumentEvent event) {
345: long i = System.currentTimeMillis();
346: if (i > lastRun + 1000) {
347: lastRun = i;
348: runVerifier();
349: }
350: }
351: });
352: }
353:
354: }
|