package org.eclipse.dltk.tcl.internal.ui.text;
import java.net.URI;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.core.IExternalSourceModule;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.internal.core.ModelManager;
import org.eclipse.dltk.launching.IInterpreterInstall;
import org.eclipse.dltk.launching.ScriptRuntime;
import org.eclipse.dltk.tcl.core.TclPackagesManager;
import org.eclipse.dltk.tcl.core.packages.TclModuleInfo;
import org.eclipse.dltk.tcl.core.packages.TclPackagesFactory;
import org.eclipse.dltk.tcl.core.packages.TclProjectInfo;
import org.eclipse.dltk.tcl.core.packages.TclSourceEntry;
import org.eclipse.dltk.tcl.core.packages.UserCorrection;
import org.eclipse.dltk.tcl.internal.ui.TclUI;
import org.eclipse.dltk.ui.editor.IScriptAnnotation;
import org.eclipse.dltk.ui.text.IAnnotationResolution;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.IMarkerResolution;
final class TclSourceMarkerResolution
implements IMarkerResolution, IAnnotationResolution {
private String sourceName;
private IScriptProject project;
private ISourceModule module;
public TclSourceMarkerResolution(String pkgName,
IScriptProject scriptProject, ISourceModule module) {
this.sourceName = pkgName;
this.project = scriptProject;
this.module = module;
}
@Override
public String getLabel() {
return "Add user specified source file location to buildpath";
}
private static IPath resolveSourceValue(IPath folder, String source,
IEnvironment environment) {
IPath valuePath = null;
if (environment.isLocal()) {
valuePath = Path.fromOSString(source);
} else {
source = source.replace('\\', '/');
valuePath = Path.fromPortableString(source);
}
IPath sourcedPath = null;
if (valuePath.isAbsolute()) {
sourcedPath = valuePath;
} else {
if (TclPackagesManager.isValidName(source)) {
sourcedPath = folder.append(valuePath);
}
}
return sourcedPath;
}
public static boolean fixAvailable(ISourceModule module, String source) {
if (module == null || !module.exists()) {
return false;
}
IEnvironment env = EnvironmentManager.getEnvironment(module);
IPath modulePath = module.getPath();
if (module.getResource() != null) {
modulePath = module.getResource().getLocation();
if (modulePath == null) {
URI uri = module.getResource().getLocationURI();
if (uri != null) {
IFileHandle file = env.getFile(uri);
if (file != null) {
modulePath = file.getPath();
}
}
}
}
IPath sourcePath = resolveSourceValue(modulePath.removeLastSegments(1),
source, env);
if (sourcePath == null) {
return false;
}
IFileHandle file = env.getFile(sourcePath);
if (file != null && file.exists() && file.isFile()) {
return true;
}
return false;
}
private boolean resolve() {
final IInterpreterInstall install;
try {
install = ScriptRuntime.getInterpreterInstall(project);
if (install != null) {
// Ask for user correction.
IEnvironment env = EnvironmentManager
.getEnvironment(this.module);
IPath modulePath = module.getPath();
if (module.getResource() != null) {
modulePath = module.getResource().getLocation();
if (modulePath == null) {
URI uri = module.getResource().getLocationURI();
if (uri != null) {
IFileHandle file = env.getFile(uri);
if (file != null) {
modulePath = file.getPath();
}
}
}
}
IPath sourcePath = resolveSourceValue(
modulePath.removeLastSegments(1), this.sourceName, env);
if (sourcePath == null) {
return false;
}
TclProjectInfo tclProject = TclPackagesManager
.getTclProject(project.getElementName());
String handle = this.module.getHandleIdentifier();
TclModuleInfo info = tclProject.findModule(handle);
if (info == null) {
// This is almost impossibly situation.
info = TclPackagesFactory.eINSTANCE.createTclModuleInfo();
info.setHandle(handle);
info.setExternal(
this.module instanceof IExternalSourceModule);
TclSourceEntry sourceEntry = TclPackagesFactory.eINSTANCE
.createTclSourceEntry();
sourceEntry.setStart(-1);
sourceEntry.setEnd(-1);
sourceEntry.setValue(sourceName);
info.getSourced().add(sourceEntry);
tclProject.getModules().add(info);
}
UserCorrection correction = TclPackagesFactory.eINSTANCE
.createUserCorrection();
correction.setOriginalValue(sourceName);
correction.getUserValue().add(sourcePath.toString());
info.getSourceCorrections().add(correction);
TclPackagesManager.save();
// We need to fire external archives change.
ModelManager.getModelManager().getDeltaProcessor()
.checkExternalChanges(new IModelElement[] { project },
new NullProgressMonitor());
}
} catch (CoreException e) {
TclUI.error("require package resolve error", e); //$NON-NLS-1$
}
return false;
}
@Override
public void run(final IMarker marker) {
resolve();
}
@Override
public void run(IScriptAnnotation annotation, IDocument document) {
resolve();
}
}