/*
* #%~
* org.overture.ide.plugins.coverageeditor
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.ide.plugins.coverageeditor.editor;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Vector;
import org.eclipse.core.internal.resources.Folder;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.overture.ast.lex.LexLocation;
import org.overture.ast.util.definitions.ClassList;
import org.overture.ast.util.modules.ModuleList;
import org.overture.ide.core.resources.IVdmProject;
import org.overture.ide.plugins.coverageeditor.Activator;
import org.overture.ide.ui.editor.core.VdmDocument;
import org.overture.ide.ui.editor.core.VdmDocumentProvider;
import org.overture.parser.config.Properties;
import org.overture.parser.lex.BacktrackInputReader.ReaderType;
import org.overture.parser.lex.LexTokenReader;
import org.overture.parser.syntax.ClassReader;
import org.overture.parser.syntax.ModuleReader;
@SuppressWarnings("restriction")
public abstract class CoverageEditor
{
public class CoverageDocumentProvider extends VdmDocumentProvider
{
@Override
protected IDocument createDocument(Object element) throws CoreException
{
if (element instanceof FileEditorInput)
{
IFile file = ((FileEditorInput) element).getFile();
if (!file.exists() || file.getName().endsWith("covtbl"))
{
return super.createEmptyDocument();
} else
{
VdmDocument doc = (VdmDocument) super.createDocument(element);
IVdmProject project = (IVdmProject) file.getProject().getAdapter(IVdmProject.class);
Assert.isNotNull(project, "Project could not be adapted");
doc.setSourceUnit(new CoverageSourceUnit(project, file));
return doc;
}
}
return super.createEmptyDocument();
}
}
private IFile selectedFile;
private File sourceFile;
private String charset;
private String content;
IFile vdmSourceFile = null;
String vdmCoverage = null;
List<StyleRange> styleRanges = new Vector<StyleRange>();
// SourceReferenceManager sourceReferenceManager = null;
IVdmProject project = null;
@SuppressWarnings({ "deprecation" })
public void init(IEditorSite site, IEditorInput input)
throws PartInitException
{
IPath path = ((IPathEditorInput) input).getPath();
try
{
IContainer[] hh = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocation(path);
for (IContainer c : hh)
{
if (c instanceof Folder)
{
((Folder) c).getProject();
}
}
IFile res = ((FileEditorInput) input).getFile();
if (res.exists())
{
charset = res.getCharset();
sourceFile = res.getLocation().toFile();
content = readFile(res);
vdmSourceFile = (IFile) res;
} else
{
throw new PartInitException("File not found: "
+ res.getLocationURI().toASCIIString());
}
project = (IVdmProject) res.getProject().getAdapter(IVdmProject.class);
if (project == null)
{
Assert.isTrue(true, "Coverage project not VDM");
}
String fileName = vdmSourceFile.getName().substring(0, vdmSourceFile.getName().length() - 3)
+ ".covtbl"; // selectedFile.getName().substring(0,
// selectedFile.getName().lastIndexOf('.'));
IResource covTbl = findMember(res.getParent(), fileName);// project.findMember(fileName);
if (covTbl instanceof IFile)
{
selectedFile = (IFile) covTbl;
vdmCoverage = readFile(selectedFile);
}
} catch (IOException e)
{
if (Activator.DEBUG)
{
e.printStackTrace();
}
} catch (CoreException e)
{
if (Activator.DEBUG)
{
e.printStackTrace();
}
}
}
public void createPartControl(Composite parent)
{
if (vdmSourceFile == null || !vdmSourceFile.exists())
{
if (vdmCoverage != null)
{
getEditorSourceViewer().getTextWidget().setText(vdmCoverage);
}
return;
}
Display display = getEditorSourceViewer().getTextWidget().getDisplay();
Color green = new Color(display, 165, 249, 171);// display.getSystemColor(SWT.COLOR_GREEN);
Color red = new Color(display, 252, 114, 114);// display.getSystemColor(SWT.COLOR_RED);
Color black = display.getSystemColor(SWT.COLOR_BLACK);
LexLocation.resetLocations();
// LexLocation.clearLocations();
Properties.parser_tabstop = 1;
LexTokenReader ltr = null;
try
{
ltr = new LexTokenReader(content, project.getDialect(), sourceFile, charset, getReaderType(sourceFile));
} catch (CoreException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
switch (project.getDialect())
{
case VDM_PP:
case VDM_RT:
{
ClassReader reader;
ClassList classes = new ClassList();
reader = new ClassReader(ltr);
classes.addAll(reader.readClasses());
}
break;
case VDM_SL:
{
ModuleReader reader;
ModuleList modules = new ModuleList();
reader = new ModuleReader(ltr);
modules.addAll(reader.readModules());
}
break;
case CML:
break;
}
BufferedReader br;
if (selectedFile != null)
{
try
{
for (LexLocation l : LexLocation.getSourceLocations(sourceFile)) // Only
// executable
{
if (l.hits == 0)
{
int start = l.getStartOffset();
int end = l.getEndOffset();
if (start < content.length() && start < end
&& end < content.length())
{
styleRanges.add(new StyleRange(start - 1, end
- start, black, red));
}
}
}
if (!selectedFile.isSynchronized(IResource.DEPTH_ZERO))
{
selectedFile.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
}
br = new BufferedReader(new BufferedReader(new InputStreamReader(selectedFile.getContents())));
String line = br.readLine();
while (line != null)
{
if (line.charAt(0) == '+')
{
// Hit lines are "+line from-to=hits"
int s1 = line.indexOf(' ');
int s2 = line.indexOf('-');
int s3 = line.indexOf('=');
int lnum = Integer.parseInt(line.substring(1, s1));
int from = Integer.parseInt(line.substring(s1 + 1, s2));
int to = Integer.parseInt(line.substring(s2 + 1, s3));
int hits = Integer.parseInt(line.substring(s3 + 1));
for (LexLocation l : LexLocation.getSourceLocations(sourceFile)) // Only
// executable
{
if (l.startLine == lnum && l.startPos == from
&& l.endPos == to)
{
l.hits += hits;
int start = l.getStartOffset();// converter.getStartPos(l);
int end = l.getEndOffset();// converter.getEndPos(l);
if (start < content.length() && start < end
&& end < content.length())
{
styleRanges.add(new StyleRange(start - 1, end
- start, black, green));
}
break;
}
}
}
line = br.readLine();
}
br.close();
} catch (IOException e)
{
if (Activator.DEBUG)
{
e.printStackTrace();
}
} catch (CoreException e)
{
if (Activator.DEBUG)
{
e.printStackTrace();
}
}
} else
{
MessageDialog.openError(getEditorSourceViewer().getTextWidget().getShell(), "Error opening coverage editor", "No coverage table table info found.");
}
for (StyleRange styleRange : styleRanges)
{
try
{
if (0 <= styleRange.start
&& styleRange.start + styleRange.length <= getEditorSourceViewer().getTextWidget().getCharCount())
{
getEditorSourceViewer().getTextWidget().replaceStyleRanges(styleRange.start, styleRange.length, new StyleRange[] { styleRange });
} else
{
System.err.println("Coverage range not valid: "
+ styleRange);
}
} catch (Exception e)
{
e.printStackTrace();
}
}
getEditorSourceViewer().getTextWidget().setEditable(false);
}
protected ReaderType getReaderType(File file) throws CoreException
{
return ReaderType.Latex;
}
protected abstract ISourceViewer getEditorSourceViewer();
protected abstract void setEditorDocumentProvider(IDocumentProvider provider);
public void setEditorDocumentProvider()
{
setEditorDocumentProvider(new CoverageDocumentProvider());
}
public static IResource findMember(IResource resource, String memberName)
throws CoreException
{
if (resource != null && resource.getName().equals(memberName))
{
return resource;
} else if (!(resource instanceof org.eclipse.core.internal.resources.File))
{
IResource[] members = ((IContainer) resource).members();
for (int i = 0; i < members.length; i++)
{
IResource tmp = findMember(members[i], memberName);
if (tmp != null)
{
return tmp;
}
}
}
return null;
}
public static String readFile(IFile file) throws IOException, CoreException
{
if (!file.isSynchronized(IResource.DEPTH_ZERO))
{
file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
}
BufferedReader inputStream = new BufferedReader(new InputStreamReader(file.getContents(), file.getCharset()));
StringBuilder sb = new StringBuilder();
int inLine;
while ((inLine = inputStream.read()) != -1)
{
sb.append((char) inLine);
}
inputStream.close();
return sb.toString();
}
}