Hi,
In an Eclipse Apllication (Ganimede) I developped some ecore extended editors.
One of the added features is navigation of links (EReferences) inter and intra model and the navigation of html links to ecore elements.
This is the context:
- an user can generate an html report (in the project or to an external location) using an extended feature of the ecore editor;
- the report is open soon in the eclipse html editor.
- The html report contains some hyperlinks to ecore elements (EPackages, EClass, EStructuralFeatures or some othe types defined in some custom models)
- Clicking to the link the user gets the proper editor open with the diserd element selected.
I optained this (in a temporary fashion) in this tricky way:
- An example of a generated link:
HTML Code:
<a href="javascript:openResource('/UseCases/schemas/Customer/UseCase1.ecore#_9d3tUDQlEd6iEbEpxJsjPA')">UseCase1</a>
- Each html report contains in the header the following line:
HTML Code:
<script src="http://127.0.0.1:2602/help/topic/com.pjsoft.ECorePlus.editor/liveHTML.js"></script>
where the port number has been set in the eclipse application config file
- This is an extract of the liveHTML.js file:
Code:
...
document.write("<iframe name='_liveHELPIFrame' id='_liveHELPIFrame' style='display:none'></iframe>");
...
function openResource(path){
liveAction("com.pjsoft.ECorePlus.editor",
"com.pjsoft.ecore.plus.OpenResourceFromBrowserAction",
path);
}
...
function liveAction(pluginId, className, argument)
{
var helpTop=findHelpTop();
if (helpTop != null && helpTop.liveActionInternal){
return helpTop.liveActionInternal(helpTop, pluginId, className, argument);
} else if (helpTop == self){
var url= window.location.href;
var i = url.indexOf("?");
if(i>0)
url=url.substring(0, i);
i = url.indexOf("/ntopic/");
url=url.substring(0, i+1);
var encodedArg=encodeURIComponent(argument);
url="http://127.0.0.1:2602/help/"+url+"livehelp/?pluginID="+pluginId+"&class="+className+"&arg="+encodedArg+"&nocaching="+Math.random();
window.open(url, "_liveHELPIFrame");
}
}
...
- This is the class from the script:
Code:
package com.pjsoft.ecore.plus;
import ...
public class OpenResourceFromBrowserAction implements ILiveHelpAction {
private String data;
public void setInitializationString(String data) {
this.data = data;
}
public void run() {
WorkbenchUtil.openURI(data);
}
}
- And last but not least, a fragment of the class that makes the most of the job:
Code:
m.pjsoft.ecore.plus.util;
import ...
public class WorkbenchUtil {
private static IWorkbench workbench=Workbench.getInstance();
private static IWorkspace workspace = ResourcesPlugin.getWorkspace();
private static IWorkspaceRoot wsRoot = workspace.getRoot();
static{
workbench.getHelpSystem().displayHelp(); //TODO: find another way to turn on the help server for navigating resource links in html reports
}
private WorkbenchUtil() {
}
..
public static final int HREF_ANCHOR=0;
public static final int HREF_INTERNAL=1;
public static final int HREF_IDE=2;
public static String mkHtmlHref(Object obj, String text, int type){
if(text==null)
text="";
if(obj==null)
return text;
EObject eobj=null;
Resource res;
String id=null;
if(obj instanceof EObject){
eobj=(EObject)obj;
res=eobj.eResource();
}else if(obj instanceof Resource){
res=(Resource)obj;
if(!res.getContents().isEmpty())
eobj=res.getContents().get(0);
}else{
return text;
}
if(eobj!=null){
if(res instanceof XMIResource)
id=((XMIResource)res).getID(eobj);
if(id==null)
id=EcoreUtil.getID(eobj);
if(id==null)
id=res.getURIFragment(eobj);
}
String link=null;
switch(type){
case HREF_INTERNAL:
link = "<a href=\"#"+id+"\">"+text+"</a>";
break;
case HREF_IDE:
link="<a href=\"javascript:openResource('"
+res.getURI().toPlatformString(true)
+(id!=null ? "#"+id : "")+"')\">"+text+"</a>";
break;
default:
link="<a name=\""+id+"\"></a>";
break;
}
return link;
}
public static String mkHtmlLink(Object obj, String text){
return mkHtmlHref(obj, text, HREF_IDE);
}
public static String mkHtmlRef(Object obj, String text){
return mkHtmlHref(obj, text, HREF_INTERNAL);
}
public static String mkHtmlAnchor(Object obj){
return mkHtmlHref(obj, null, HREF_ANCHOR);
}
...
public static IFile getIFileForFullPath(String fullPath) {
try{
return wsRoot.getFile(new Path(fullPath));
}catch(Exception ex){
System.err.println("in getIFileForFullPath-->"+ex.toString());
}
return null;
}
public static void openURI(final String theUri) {
// Active help does not run on the UI thread, so we must use syncExec
Display.getDefault().syncExec(new Runnable() {
public void run() {
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
if (window == null)
return;
IWorkbenchPage page = window.getActivePage();
final IWorkbenchPart activePart = page.getActivePart();
Shell shell = window.getShell();
shell.setMinimized(false);
shell.forceActive();
String data=theUri;
URI uri=URI.createURI(data);
final String id=uri.fragment();
data=uri.trimFragment().toString();
final IFile resFile = WorkbenchUtil.getIFileForFullPath(data);
if (activePart instanceof ISetSelectionTarget) {
final ISelection targetSelection = new StructuredSelection(resFile);
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
((ISetSelectionTarget) activePart)
.selectReveal(targetSelection);
}
});
}
FileEditorInput ei = new FileEditorInput(resFile);
IEditorDescriptor ed = workbench.getEditorRegistry().getDefaultEditor(resFile.getFullPath().toString());
try {
IEditorPart ep = page.openEditor(ei, ed.getId());
if(id!=null && ep.getClass().getSimpleName().startsWith("ECorePlus")){
gotoID(ep, id);
}
} catch (PartInitException e) {
e.printStackTrace();
}
}
});
}
public static void gotoID(IEditorPart ep, String id){
Object selObject=((StructuredSelection)ep.getEditorSite().getSelectionProvider().getSelection()).getFirstElement();
if(selObject==null)
return;
if(selObject instanceof EObject)
selObject=((EObject)selObject).eResource();
if(selObject instanceof XMIResource){
XMIResource xr=(XMIResource)selObject;
selObject = xr.getEObject(id);
if(selObject!=null)
((IViewerProvider)ep).getViewer().setSelection(
new TreeSelection(new TreePath(new Object[]{selObject})), true);
}
}
}
Well, sorry for the long preface, here the questions:
- there is a canonical (or however better) way to get the same behaviour?
- if this is a good approach, how can I substitute this line in WorkbenchUtil:
Code:
static{
workbench.getHelpSystem().displayHelp(); //TODO: find another way to turn on the help server for navigating resource links in html reports
}
that are used to initialize the help system used for navigating?
This way, the first time I use the http engine, I get the help window open (of course a not desire effect), so how can I initialize the http/help engine w/o opening the help window?
Thanks to all the guys having the patience to read the whole romance....