# Eclipse Standalone Help - runUI und diverse andere Baustellen



## namenlos123 (28. Mai 2010)

Hallo liebe Community,

erstmal ein "Servus" meinerseits. :meld:
Ich bin seit ca. 2 Wochen auf der Suche nach einem geeigneten Tutorial fuer eine Eclipse Standalone Help. Die Seite Help - Eclipse SDK hat mir in dieser Sache nur bedingt geholfen. Ich habe eine Standalone mit OSGi und den dazugehoerigen Bundles zum Starten gebracht, nur leider ohne meine TOCs.

Ich vermute das Problem liegt am Activator.java, denn ich fuer die Ausfuehrung meiner Standalone verwende. Deshalb bin ich gerade dabei herauszufinden, wo und wie ich den alles ohne einen Activator generieren kann.

Meine Frage kann ich leider nicht ohne weiteres leicht formulieren, da mir selbst die Kenntnisse mit PDEs fehlen. Ich versuch's trotzdem mal... Was fuer Dependencies brauche ich alles in meiner Plugin-Klasse "HelpSystem"?

Falls der Code mehr Erlaeuchtung bringen kann, werde ich ihn gerne posten. Ich danke schon mal fuer jeden kleinen Tip/Hilfe/Code-Schnipsel. 


Gruss,
namenlos.


----------



## namenlos123 (28. Mai 2010)

Ich muss mal so generelle Fragen hier im Forum aufschreiben, damit ich sie nicht vergesse...

Muss ich zwingend eine Workbench erstellen (PlatformUI) um eine Standalone-UI anzuzeigen?


----------



## Wildcard (28. Mai 2010)

> Muss ich zwingend eine Workbench erstellen (PlatformUI) um eine Standalone-UI anzuzeigen?


Was meinst du mit Standalone UI? Die Standalone Help läuft in einem Jetty Server und ist vom Browser erreichbar, dafür brauchst du also keine PlatformUI und noch nichtmal SWT. In der Eclipse IDE selbst wird diese Hilfe einfach in einem SWT Browser Widget gerendert. Für eine Standalone Applikation musst du halt irgendwo anders einen Browser bekommen oder zumindest etwas das HTML rendern kann.




> Meine Frage kann ich leider nicht ohne weiteres leicht formulieren, da mir selbst die Kenntnisse mit PDEs fehlen. Ich versuch's trotzdem mal... Was fuer Dependencies brauche ich alles in meiner Plugin-Klasse "HelpSystem"?


Ich verstehe nicht so ganz was du wissen möchtest? Hast du den Help Server erfolgreich starten können? Wenn nein, wie versuchst du ihn derzeit zu starten?


----------



## namenlos123 (31. Mai 2010)

Wildcard hat gesagt.:


> Was meinst du mit Standalone UI?


Mit Standalone-UI meine ich den SWT Browser, welcher mir ein Help-Fenster oeffnet. Diesen möchte ich gerne "starten", falls dieser schon fertig irgendwo in einem Bundle startbereit liegt.



Wildcard hat gesagt.:


> Die Standalone Help läuft in einem Jetty Server und ist vom Browser erreichbar, dafür brauchst du also keine PlatformUI und noch nichtmal SWT. In der Eclipse IDE selbst wird diese Hilfe einfach in einem SWT Browser Widget gerendert. Für eine Standalone Applikation musst du halt irgendwo anders einen Browser bekommen oder zumindest etwas das HTML rendern kann.


Wo kann ich diesen SWT-Browser starten, bzw. wo findet ich den Code dazu?



Wildcard hat gesagt.:


> Ich verstehe nicht so ganz was du wissen möchtest? Hast du den Help Server erfolgreich starten können? Wenn nein, wie versuchst du ihn derzeit zu starten?


Also, der "Server"(?) wartet auf eine GUI im "runUI()". 

Ich versuche gerade eine Standalone-Help-Application ohne einen Activator zum laufen zu bringen. So wie es IBM auch mit ihrer Help in Eclipse macht, will ich diese Applikation standalone laufen lassen, ohne Eclipse. Soweit ich das beurteilen kann, ist das ja schon moeglich.

Also eine Workbench ist dann wohl unnoetig, wenn ich da einen SWT-Browser verwende, oder? Ich such dann mal den SWT-Browser mal... :rtfm:

Danke fuer deine Unterstuetzung Wildcard.:toll:


p.s.: ich liebe eure smilies.


----------



## Wildcard (31. Mai 2010)

Das SWT Browser widget embedded lediglich einen Betriebssystem Browser (Firefox bei Linux, IE, bei Windows,...).
Handelt es sich denn um eine SWT Anwendung? Wenn nein, dann solltest du vielleicht besser die Desktop Klasse der JRE 6 verwenden um den System Browser aufzurufen.


----------



## namenlos123 (31. Mai 2010)

ok, hab die SWT-Klasse "org.eclipse.swt.browser" gefunden. Ob mir das jetzt in meinem Fall weiterbringt, kann ich jetzt nicht beurteilen. Zumindest weiss ich das diese Fenster in SWT-Jargon "Shell" bezeichnet werden. 

Ich versteh noch immer nicht wie ich die org.eclipse.help.standalone zum laufen kriegen soll. Ich poste mal mein Problem-Codeteil, damit ihr besser zu verstehen koennt was ich das geschrieben habe. Vielleicht habe ich da was nicht richtig verstanden.


```
if(!PlatformUI.isWorkbenchRunning()) {
            PlatformUI.createDisplay();
        }
        
//        String[] options = null;
//        Help helpSystem = new Help(options);
        
        //try running UI loop if possible
        runUI();
//      run a headless loop;
        while (status == STATE_RUNNING) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ie) {
                break;
            }
        }
        releaseLock();
        if (status == STATE_RESTARTING) {
            return EXIT_RESTART;
        }
        return EXIT_OK;
    }
    
    private void runUI() throws BundleException {
        // TODO Auto-generated method stub
        invoke("run");
    }

    private static void invoke(String method) throws BundleException {
        final String HELP_UI_PLUGIN_ID = "org.eclipse.help.ui";
        final String LOOP_CLASS_NAME = "org.eclipse.help.ui.internal.HelpUIEventLoop";
        try {
            Bundle bundle = Platform.getBundle(HELP_UI_PLUGIN_ID);
            if (bundle == null) {
                return;
            }
            Class c = bundle.loadClass(LOOP_CLASS_NAME);
            Method m = c.getMethod(method, new Class[]{});
            m.invoke(null, new Object[]{});
        } 
        catch (Exception e) {
            throw new BundleException("Bundle not found", e);
        }
    }
```


----------



## namenlos123 (31. Mai 2010)

Wildcard hat gesagt.:


> Das SWT Browser widget embedded lediglich einen Betriebssystem Browser (Firefox bei Linux, IE, bei Windows,...).
> Handelt es sich denn um eine SWT Anwendung? Wenn nein, dann solltest du vielleicht besser die Desktop Klasse der JRE 6 verwenden um den System Browser aufzurufen.


Nun, es handelt sich in dem Fall schon um eine SWT-Applikation und zwar um die Eclipse-Help-Applikation. Soweit ich das ganze verstehe, benutzt Eclipse fuer seine Hilfe SWT und keine Standalone. Irre ich mich da oder nicht?

In welchem Bundle befindet sich den der System-Browser?


----------



## namenlos123 (31. Mai 2010)

HelpUIEventLoop.run() line: 41	


```
while (HelpApplication.isRunning()) {
				try {
					if (!display.readAndDispatch()) {
						display.sleep();
					}
				} catch (Throwable t) {
					HelpBasePlugin.logError(t.getMessage(), t);
				}
			}
```

Also gut... hier schlaeft mein EDT und wartet auf den Beenden-Befehl, der dann spaeter ueber die GUI gegeben werden soll. Jetzt muss ich noch herausfinden wie die IBM-Leutz die Hilfe gebaut haben und ob es schon was fertiges irgendwo in JDK-Bundles existiert.


----------



## namenlos123 (31. Mai 2010)

Auf java2s.com gibt es schoene AWT/SWT-Codes zu sehen. Ich versuch mal zweit Threads starten zu lassen, um in einer die GUI zu starten.


----------



## namenlos123 (31. Mai 2010)

So, Thread laeuft und mein SWT-Browser startet gemuetlich, aber irgendwie bin ich unzufrieden mit dieser Loesung... eigentlich wollte ich den Eclipse-Help-Browser erstellen.

Wo kann man den in welchem Bundle finden? Ich hab schon org.eclipse.help.ui durchsucht und dort einen Browser-Ordner gefunden. Ist das Bundle in meinem Fall die Loesung? ???:L

Gruss,
namenlos.


----------



## namenlos123 (31. Mai 2010)

Ok, mein SWT-Browser hab ich mal ueber Bord geworfen und in der Zwischenzeit habe ich kurz mal die Idee mit EmbeddedBrowser gehabt und auch gleich in den Datenpapierkorb gepfeffert.

Jetzt glaube ich endlich auf die richtige Faehrte gekommen zu sein und zwar mit der Klasse Help in dem Bundle "org.eclipse.help.base"... :rtfm:

Falls jemand schon die Lösung zur Erstellung einer Eclipse Standalone Help besitzt, kann sich gerne hier melden. 

Gruss,
namenlos.


----------



## Wildcard (31. Mai 2010)

Ich glaube du missverstehst einige Dinge. 


> Nun, es handelt sich in dem Fall schon um eine SWT-Applikation und zwar um die Eclipse-Help-Applikation. Soweit ich das ganze verstehe, benutzt Eclipse fuer seine Hilfe SWT und keine Standalone. Irre ich mich da oder nicht?


Ist deine Anwendung (nicht die Hilfe) denn in SWT geschrieben? Wie genau stellst du dir die Interaktion zwischen deiner Anwendung und der Hilfe vor?
Die Eclipse Hilfe (wenn du Help -> Help Contents anklickst) ist keine SWT Gui! Das ist lediglich ein embedded Browser. Der Eclipse Help Server läuft als lokaler Webserver und liefert HTML Seiten an den Browser an. Sofern deine eigentlich Anwendung also nicht SWT basiert es brauchst du erstmal auch kein SWT.


> In welchem Bundle befindet sich den der System-Browser?


Verstehe die Frage nicht. Der Systembrowser ist auf deinem Betriebssystem installiert.



> Jetzt muss ich noch herausfinden wie die IBM-Leutz die Hilfe gebaut haben und ob es schon was fertiges irgendwo in JDK-Bundles existiert.


Von welcher IBM Anwendung sprichst du und was meinst du mit fertigem JDK Bundle?

Also um das nochmal ganz klar zu sagen, Eclipse Help ist primär eine Webanwendung die im Browser dargestellt wird. Um zu testen solltest du daher auch erstmal nur den Help Server auf einem bestimmten Port starten und dann mit zB Firefox testen ob du den Help Server erreichst.
Danach kann man sich dann um die Integration in die eigene Anwendung kümmern.


----------



## namenlos123 (1. Jun 2010)

Ok, es kann sein, dass ich mein Ziel nicht ganz erklaert habe. Ich versuche es mal mit der Beantwortung deiner Fragen, Wildcard.



Wildcard hat gesagt.:


> Ist deine Anwendung (nicht die Hilfe) denn in SWT geschrieben? Wie genau stellst du dir die Interaktion zwischen deiner Anwendung und der Hilfe vor?


Die Anwendung soll die Eclipse Help Standalone sein. Es gibt sonst keine andere. Ich versuche die Hilfe von Eclipse zu entkoppeln und fuer meine spaeteren Anwendungen als Doku-Handbuch-Bla-Programm zu verwenden. In der Hilfe (Help - Eclipse SDK) ist ja die Hilfe-Plattform auf die Eclipse-Plattform angesiedelt. Gut, beide brauchen sich. Aber ich versuche gerade minimale Klassen zu finden, um auch ohne "Team", "Workspace" oder "Workbench" die Hilfe zu starten.



Wildcard hat gesagt.:


> Die Eclipse Hilfe (wenn du Help -> Help Contents anklickst) ist keine SWT Gui! Das ist lediglich ein embedded Browser.


Ok, einen embedded Browser habe ich aus org.eclipse.help.ui mir erstellen lassen. Dieser ist mit SWT gebastelt worden, soweit ich das im Quellcode lese. ???:L
Oder meinst du mit "embedded Browser" etwas anderes?



Wildcard hat gesagt.:


> Der Eclipse Help Server läuft als lokaler Webserver und liefert HTML Seiten an den Browser an.


Welche Klasse erstellt den Eclipse Help Server? Ist JettyHelpServer dieser?



Wildcard hat gesagt.:


> Verstehe die Frage nicht. Der Systembrowser ist auf deinem Betriebssystem installiert.


Ja, ich meinte die Desktop Klasse der JRE 6 verwenden um den System Browser aufzurufen. Das ist doch ein selbstgeschriebener von Eclipse (in SWT/AWT) in irgendeinem Bundle, oder?



Wildcard hat gesagt.:


> Von welcher IBM Anwendung sprichst du und was meinst du mit fertigem JDK Bundle?


Mit "IBM Anwendung" ich lediglich Eclipse Help gemeint. Sorry, fuer die unklare Aussage. Mit den JDK Bundles meine ich die Bundles in Plugins im Installationspfad von Eclipse.



Wildcard hat gesagt.:


> Also um das nochmal ganz klar zu sagen, Eclipse Help ist primär eine Webanwendung die im Browser dargestellt wird. Um zu testen solltest du daher auch erstmal nur den Help Server auf einem bestimmten Port starten und dann mit zB Firefox testen ob du den Help Server erreichst.
> Danach kann man sich dann um die Integration in die eigene Anwendung kümmern.


Kann ich nun die Standalone-Help ohne Webbrowser starten? Ich bin jetzt voellig verwirrt. In der Architektur-Erlaeuterung in der Eclipse-Hilfe-Webseite habe ich das so verstanden, dass ich das minimal laufen lassen kann.

Puh, sorry fuer die langatmige Antwort, aber ich glaube jetzt haben sich einige Fragen beantwortet.


Gruss,
namenlos.


----------



## Wildcard (1. Jun 2010)

> Die Anwendung soll die Eclipse Help Standalone sein. Es gibt sonst keine andere. Ich versuche die Hilfe von Eclipse zu entkoppeln und fuer meine spaeteren Anwendungen als Doku-Handbuch-Bla-Programm zu verwenden. In der Hilfe (Help - Eclipse SDK) ist ja die Hilfe-Plattform auf die Eclipse-Plattform angesiedelt. Gut, beide brauchen sich. Aber ich versuche gerade minimale Klassen zu finden, um auch ohne "Team", "Workspace" oder "Workbench" die Hilfe zu starten.


Hmm, die Eclipse Help ist deine Anwendung?
Wie soll ein Eclipse RCP denn aussehen der *nur* aus Help besteht? ???:L
Willst du ein leeres Fenster mit einem Help Menü? Das scheint mir wenig wahrscheinlich.
Ich habe vermutet das du Eclipse Help als Ersatz für Java Help verwenden willst. Ist das soweit richtig?
Wenn ja, dann gibt es absolut keinen Grund für dich überhaupt mit SWT und Eclipse UI anzufangen. Eclipse Help startet einen Jetty Webserver der HTML Seiten ausliefert. Diese Seiten können im Browser geöffnet werden und schon hast du eine Eclipse Hilfe.



> Ok, einen embedded Browser habe ich aus org.eclipse.help.ui mir erstellen lassen. Dieser ist mit SWT gebastelt worden, soweit ich das im Quellcode lese.
> Oder meinst du mit "embedded Browser" etwas anderes?


Das Browser Widget integriert wie gesagt lediglich den Browser den das Betriebssystem mitbringt, IE, Mozilla XULRunner (Firefox),... Wenn du einfach das Hilfe Fenster anzeigen willst, dann brauchst du dafür kein SWT!



> Welche Klasse erstellt den Eclipse Help Server? Ist JettyHelpServer dieser?


Würde ich vermuten, kenne die Interna der Hilfe aber nicht im Detail.


> Ja, ich meinte die Desktop Klasse der JRE 6 verwenden um den System Browser aufzurufen. Das ist doch ein selbstgeschriebener von Eclipse (in SWT/AWT) in irgendeinem Bundle, oder?


Nein, es gibt keinen Eclipse Browser, das Browser Widget inkludiert wie gesagt nur den Browser des Betriebssystems (mittels OLE, COM,...), daher verstehe ich auch nicht warum du eine Workbench UI hochziehen willst oder SWT Code schreiben willst.



> Kann ich nun die Standalone-Help ohne Webbrowser starten? Ich bin jetzt voellig verwirrt. In der Architektur-Erlaeuterung in der Eclipse-Hilfe-Webseite habe ich das so verstanden, dass ich das minimal laufen lassen kann.


Du kannst den Helpserver natürlich ohne Webbrowser starten, aber du siehst davon nichts, weil er keine Oberfläche hat. Das grafische Frontend für den Benutzer  ist der Browser. Vergleich es mit PHPMyAdmin oder so. Du brauchst keinen Browser um PHPMyAdmin zu starten, aber ohne Browser als Frontend nützt dir das nicht viel.


----------



## Wildcard (1. Jun 2010)

Übrigens, das hilft dir vielleicht:
Help - Eclipse SDK


----------



## namenlos123 (7. Jun 2010)

Juhu, erste Erfolge sind zu vermelden. :toll:




Wildcard hat gesagt.:


> Hmm, die Eclipse Help ist deine Anwendung?
> Wie soll ein Eclipse RCP denn aussehen der *nur* aus Help besteht? ???:L
> Willst du ein leeres Fenster mit einem Help Menü? Das scheint mir wenig wahrscheinlich.


Ich will nur das Grundgeruest benutzen. Bedeutet, linker Frame sind meine TOCs zu finden, rechter Frame mein Inhalt, Suche-Funktion, Bookmark-Funktion, Index-Seite, ... also alles was es sonst auch in der Eclipse-Help sonst zu finden ist. Die TOCs(linkter Frame) lade ich dann durch XML-Files und den Inhalt(rechter Frame) fuelle ich durch HTML-Code.



Wildcard hat gesagt.:


> Ich habe vermutet das du Eclipse Help als Ersatz für Java Help verwenden willst. Ist das soweit richtig? Wenn ja, dann gibt es absolut keinen Grund für dich überhaupt mit SWT und Eclipse UI anzufangen.


Ja, das war von mir zu schwammig formuliert. Ja, ich will die Eclipse-Help verwenden. Die ist, wie du schon selbst sagtest, mit einem System-Browser zusammen. Gefunden habe ich nun auch die .class womit ich eine Standalone-Help ausfuehren kann. Schau mal die DefaultHelpUI.class an. Da wird dann auch ne SWT-Shell gestartet.



Wildcard hat gesagt.:


> Eclipse Help startet einen Jetty Webserver der HTML Seiten ausliefert. Diese Seiten können im Browser geöffnet werden und schon hast du eine Eclipse Hilfe.


Bis jetzt hab ich es noch nicht selbst durchtracen koennen. Meine Loesung ist wohl nicht so konzipiert, dass sie mit Jetty arbeitet. In der help.base ist ein JettyHelpServer zu finden. Koennte sein, dass dieser verwendet wird. Hmm, wenn ich so recht ueberlege... Er greift ja auf meinen localhost, also sollte doch ja irgend-"etwas" als Server da sein, der meine ganzen HTML und XML Files verwendet. Naja, muss mich da auch erst schlau machen. :rtfm:




Wildcard hat gesagt.:


> Das Browser Widget integriert wie gesagt lediglich den Browser den das Betriebssystem mitbringt, IE, Mozilla XULRunner (Firefox),... Wenn du einfach das Hilfe Fenster anzeigen willst, dann brauchst du dafür kein SWT!


Ja, das Browser-Widget bringt das mit sich. Leider konnte ich dieses Widget fuer meine Anforderung nicht benutzen, da die Durchsuche-Funktion, Bookmark usw. fehlen.



Wildcard hat gesagt.:


> Nein, es gibt keinen Eclipse Browser, das Browser Widget inkludiert wie gesagt nur den Browser des Betriebssystems (mittels OLE, COM,...), daher verstehe ich auch nicht warum du eine Workbench UI hochziehen willst oder SWT Code schreiben willst.


Ich will keine Workbench-UI. Ich wollte nur eine Eclipse-Standalone-Help zum Laufen bringen die ohne einer Workbench laufen sollte. Das hat jetzt endlich auch geklappt.



Wildcard hat gesagt.:


> Du kannst den Helpserver natürlich ohne Webbrowser starten, aber du siehst davon nichts, weil er keine Oberfläche hat. Das grafische Frontend für den Benutzer  ist der Browser. Vergleich es mit PHPMyAdmin oder so. Du brauchst keinen Browser um PHPMyAdmin zu starten, aber ohne Browser als Frontend nützt dir das nicht viel.


Hehe, stimmt... klar, das Backend kann immer ohne ein Frontend laufen. 

Demnaechst werde ich den code hier posten, wenn soweit alles funzt.

Gruss,
namenlos.


----------



## Wildcard (7. Jun 2010)

> Ich will nur das Grundgeruest benutzen. Bedeutet, linker Frame sind meine TOCs zu finden, rechter Frame mein Inhalt, Suche-Funktion, Bookmark-Funktion, Index-Seite, ... also alles was es sonst auch in der Eclipse-Help sonst zu finden ist. Die TOCs(linkter Frame) lade ich dann durch XML-Files und den Inhalt(rechter Frame) fuelle ich durch HTML-Code.


Du verstehst das glaube ich immer noch nicht richtig. Dieses 'Grundgerüst' ist kein Widget, es ist komplett eine HTML Seite die vom Jetty Server generiert wird, nicht nur der Help 'Inhalt' auf der rechten Seite. Es gibt dort keine SWT Buttons, keine Splitpane, alles pur HTML mit AJAX


----------



## namenlos123 (16. Jun 2010)

Wildcard hat gesagt.:


> Du verstehst das glaube ich immer noch nicht richtig. Dieses 'Grundgerüst' ist kein Widget, es ist komplett eine HTML Seite die vom Jetty Server generiert wird, nicht nur der Help 'Inhalt' auf der rechten Seite. Es gibt dort keine SWT Buttons, keine Splitpane, alles pur HTML mit AJAX


Hmm, ok. Muss ich wohl hinnehmen. 


Nun denn... hier der Code, mit dem ich eine Help erstelle... Das ganze ist ein Plugin-Project ohne Activator!!! Soll also spaeter als Application irgendwo laufen.

Thread-Klasse ruft Help-Fenster auf

```
package com.xyz.help.bootstrap;

import org.eclipse.help.ui.internal.DefaultHelpUI;

public class XYZHelpGUIThread extends Thread {
    DefaultHelpUI defaultHelpUI;

    public XYZHelpGUIThread(String name) {
        // TODO Auto-generated constructor stub
        super(name);
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        defaultHelpUI = new DefaultHelpUI();
        defaultHelpUI.displayHelp();
        super.run();
    }

    @Override
    public synchronized void start() {
        // TODO Auto-generated method stub
        super.start();
    }

}
```

Main-Klasse

```
package com.xyz.help.bootstrap;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.nio.channels.FileLock;
import java.util.Map;
import java.util.Properties;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.Platform;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.base.HelpBaseResources;
import org.eclipse.help.internal.server.WebappManager;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;

public class XYZHelpApplication implements IApplication,
        IExecutableExtension {

    private static final String APPLICATION_LOCK_FILE = ".applicationlock"; //$NON-NLS-1$
    private static final int STATE_EXITING = 0;
    private static final int STATE_RUNNING = 1;
    private static final int STATE_RESTARTING = 2;
    private static int status = STATE_RUNNING;
    private File metadata;
    private FileLock lock;

    /*
     * (non-Javadoc)
     * 
     * @seeorg.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.
     * IApplicationContext)
     */
    public synchronized Object start(IApplicationContext context)
            throws Exception {
        if (status == STATE_RESTARTING) {
            return EXIT_RESTART;
        }

        metadata = new File(Platform.getLocation().toFile(), ".metadata/"); //$NON-NLS-1$
        if (!metadata.exists() || !metadata.isDirectory()) {
            metadata.mkdirs();
        }

        if (!BaseHelpSystem.ensureWebappRunning()) {
            System.out.println(NLS.bind(
                    HelpBaseResources.HelpApplication_couldNotStart, Platform
                            .getLogFileLocation().toOSString()));
            return EXIT_OK;
        }

        if (status == STATE_RESTARTING) {
            return EXIT_RESTART;
        }

        writeHostAndPort();
        obtainLock();

        // try running UI loop if possible
        runUI();
        // run a headless loop;
        while (status == STATE_RUNNING) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ie) {
                break;
            }
        }
        releaseLock();
        if (status == STATE_RESTARTING) {
            return EXIT_RESTART;
        }
        return EXIT_OK;
    }

    private void runUI() throws BundleException {
        // TODO Auto-generated method stub

        XYZHelpGUIThread xyzHelpGUIThread = new XYZHelpGUIThread("Start-GUI");
        xyzHelpGUIThread.start();


        if (BaseHelpSystem.MODE_STANDALONE == BaseHelpSystem.getMode()) {
            // UI loop may be sleeping if no SWT browser is up
            try {
                wakeupUI();
            } catch (BundleException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        
        invoke("run");
    }

    private static void invoke(String method) throws BundleException {
        final String HELP_UI_PLUGIN_ID = "org.eclipse.help.ui";
        final String LOOP_CLASS_NAME = "org.eclipse.help.ui.internal.HelpUIEventLoop";
        try {
            Bundle bundle = Platform.getBundle(HELP_UI_PLUGIN_ID);
            if (bundle == null) {
                return;
            }
            Class c = bundle.loadClass(LOOP_CLASS_NAME);
            Method m = c.getMethod(method, new Class[] {});
            m.invoke(null, new Object[] {});
        } catch (Exception e) {
            throw new BundleException("Bundle not found", e);
        }
        
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.equinox.app.IApplication#stop()
     */
    public void stop() {
        stopHelp();

        // wait until start has finished
        synchronized (this) {
        }
        ;
    }

    /**
     * Causes help service to stop and exit
     */
    public static void stopHelp() {
        status = STATE_EXITING;
        if (BaseHelpSystem.MODE_STANDALONE == BaseHelpSystem.getMode()) {
            // UI loop may be sleeping if no SWT browser is up
            try {
                wakeupUI();
            } catch (BundleException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private static void wakeupUI() throws BundleException {
        // TODO Auto-generated method stub
        invoke("wakeup");
    }

    /**
     * Causes help service to exit and start again
     */
    public static void restartHelp() {
        if (status != STATE_EXITING) {
            status = STATE_RESTARTING;
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org
     * .eclipse.core.runtime.IConfigurationElement, java.lang.String,
     * java.lang.Object)
     */
    public void setInitializationData(IConfigurationElement configElement,
            String propertyName, Object data) {
        String value = (String) ((Map) data).get("mode"); //$NON-NLS-1$
        if ("infocenter".equalsIgnoreCase(value)) { //$NON-NLS-1$
            BaseHelpSystem.setMode(BaseHelpSystem.MODE_INFOCENTER);
        } else if ("standalone".equalsIgnoreCase(value)) { //$NON-NLS-1$
            BaseHelpSystem.setMode(BaseHelpSystem.MODE_STANDALONE);
        }
    }
    
    private void writeHostAndPort() throws IOException {
        Properties p = new Properties();
        p.put("host", WebappManager.getHost()); //$NON-NLS-1$
        p.put("port", "" + WebappManager.getPort()); //$NON-NLS-1$ //$NON-NLS-2$

        File hostPortFile = new File(metadata, ".connection"); //$NON-NLS-1$
        hostPortFile.deleteOnExit();
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(hostPortFile);
            p.store(out, null);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ioe2) {
                }
            }
        }

    }

    private void obtainLock() {
        File lockFile = new File(metadata, APPLICATION_LOCK_FILE);
        try {
            RandomAccessFile raf = new RandomAccessFile(lockFile, "rw"); //$NON-NLS-1$
            lock = raf.getChannel().lock();
        } catch (IOException ioe) {
            lock = null;
        }
    }

    private void releaseLock() {
        if (lock != null) {
            try {
                lock.channel().close();
            } catch (IOException ioe) {
            }
        }
    }

    public static boolean isRunning() {
        return status == STATE_RUNNING;
    }
}
```

Hier die Manifest:
[XML]Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: com.xyz.help.bootstrap;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: org.eclipse.help.ui;bundle-version="3.4.1"
Export-Package: com.xyz.help.bootstrap
[/XML]

Hier die Plugin.xml: (die HTML und TOC muss ich ja net jetzt noch posten,oder?  )
[XML]<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension
         id="standalone"
         name="%extension.name"
         point="org.eclipse.core.runtime.applications">
      <application
            cardinality="singleton-global"
            thread="main"
            visible="true">
         <run
               class="com.xyz.help.bootstrap.XYZHelpApplication">
            <parameter
                  name="mode"
                  value="standalone">
            </parameter>
         </run>
      </application>
   </extension>
   <extension
         point="org.eclipse.help.toc">
      <toc
            file="toc.xml"
            primary="true">
      </toc>
      <toc
            file="toc II.xml"
            primary="true">
      </toc>
   </extension>

</plugin>
[/XML]

Alles laeuft soweit, ausser das gesamte schiessen der Hintergrund-Anwendungen(Jetty und Co.). Gibts da ne Moeglichkeit auch diese zu beenden, so dass auch alles aus ist?

Gruss,
namenlos.


----------



## Wildcard (16. Jun 2010)

Wie bei jedem Java Programm endet es wenn alle non-deamon Threads beendet sind oder der Prozess abgebrochen wird.


----------



## namenlos123 (17. Jun 2010)

Ja, das war die Frage. Wie kann ich den beim "Schliessen" der Help auch die restlichen Threads beenden?


----------



## namenlos123 (21. Jun 2010)

So, soweit klappt jetzt alles. Die Hilfe meldet sich und die Hilfe beendet sich MIT all dem ganzen restlichen Kram im Hintergrund. *freu* 

Ich hab mal die DefaultHelpUI mal zur Seite gelassen und in der BaseHelpSystem eine Methode gefunden, die auch meine Help aufruft. Hier mal der Code zum ausprobieren und freuen fuer die Communitiy.


```
package com.xyz.help.bootstrap;

import java.io.File;

@SuppressWarnings("restriction")
public class XYZHelpApplication implements IApplication,
        IExecutableExtension {

    private static final String APPLICATION_LOCK_FILE = ".applicationlock"; //$NON-NLS-1$
    private static final int STATE_EXITING = 0;
    private static final int STATE_RUNNING = 1;
    private static final int STATE_RESTARTING = 2;
    private static int status = STATE_RUNNING;
    private File metadata;
    private FileLock lock;

    /*
     * (non-Javadoc) 
     * 
     * @seeorg.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.
     * IApplicationContext)
     */
    public synchronized Object start(IApplicationContext context)
            throws Exception {
        if (status == STATE_RESTARTING) {
            return EXIT_RESTART;
        }

        metadata = new File(Platform.getLocation().toFile(), ".metadata/"); //$NON-NLS-1$
        if (!metadata.exists() || !metadata.isDirectory()) {
            metadata.mkdirs();
        }

        if (!BaseHelpSystem.ensureWebappRunning()) {
            System.out.println(NLS.bind(
                    HelpBaseResources.HelpApplication_couldNotStart, Platform
                            .getLogFileLocation().toOSString()));
            return EXIT_OK;
        }

        if (status == STATE_RESTARTING) {
            return EXIT_RESTART;
        }

        writeHostAndPort();
        obtainLock();

        // try running UI loop if possible
        runUI();
        
        
        // run a headless loop;
        while (status == STATE_RUNNING) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ie) {
                break;
            }
        }
        releaseLock();
        if (status == STATE_RESTARTING) {
            return EXIT_RESTART;
        }
        return EXIT_OK;
    }

    private void runUI() throws BundleException {
        // TODO Auto-generated method stub



        if (BaseHelpSystem.MODE_STANDALONE == BaseHelpSystem.getMode()) {
            // UI loop may be sleeping if no SWT browser is up
            try {
                wakeupUI();
            } catch (BundleException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        XYZHelpUIEventLoop.run();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.equinox.app.IApplication#stop()
     */
    public void stop() {
        stopHelp();

        // wait until start has finished
        synchronized (this) {
        }
        ;
    }

    /**
     * Causes help service to stop and exit
     */
    public static void stopHelp() {
        status = STATE_EXITING;
        if (BaseHelpSystem.MODE_STANDALONE == BaseHelpSystem.getMode()) {
            // UI loop may be sleeping if no SWT browser is up
            try {
                wakeupUI();
            } catch (BundleException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private static void wakeupUI() throws BundleException {
        // TODO Auto-generated method stub
        XYZHelpUIEventLoop.wakeup();
//        invoke("wakeup");
    }

    /**
     * Causes help service to exit and start again
     */
    public static void restartHelp() {
        if (status != STATE_EXITING) {
            status = STATE_RESTARTING;
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org
     * .eclipse.core.runtime.IConfigurationElement, java.lang.String,
     * java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    public void setInitializationData(IConfigurationElement configElement,
            String propertyName, Object data) {
        String value = (String) ((Map) data).get("mode"); //$NON-NLS-1$
        if ("infocenter".equalsIgnoreCase(value)) { //$NON-NLS-1$
            BaseHelpSystem.setMode(BaseHelpSystem.MODE_INFOCENTER);
        } else if ("standalone".equalsIgnoreCase(value)) { //$NON-NLS-1$
            BaseHelpSystem.setMode(BaseHelpSystem.MODE_STANDALONE);
        }
    }
    
    private void writeHostAndPort() throws IOException {
        Properties p = new Properties();
        p.put("host", WebappManager.getHost()); //$NON-NLS-1$
        p.put("port", "" + WebappManager.getPort()); //$NON-NLS-1$ //$NON-NLS-2$

        File hostPortFile = new File(metadata, ".connection"); //$NON-NLS-1$
        hostPortFile.deleteOnExit();
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(hostPortFile);
            p.store(out, null);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ioe2) {
                }
            }
        }

    }

    private void obtainLock() {
        File lockFile = new File(metadata, APPLICATION_LOCK_FILE);
        try {
            RandomAccessFile raf = new RandomAccessFile(lockFile, "rw"); //$NON-NLS-1$
            lock = raf.getChannel().lock();
        } catch (IOException ioe) {
            lock = null;
        }
    }

    private void releaseLock() {
        if (lock != null) {
            try {
                lock.channel().close();
            } catch (IOException ioe) {
            }
        }
    }

    public static boolean isRunning() {
        return status == STATE_RUNNING;
    }
}
```


```
package com.xyz.help.bootstrap;

import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.base.HelpBasePlugin;
import org.eclipse.help.internal.server.WebappManager;
import org.eclipse.swt.widgets.Display;

@SuppressWarnings("restriction")
public class XYZHelpUIEventLoop {
    /**
     * Indicates whether run had a chance to execute and display got created
     */
    private static boolean started = false;
    /**
     * Indicates whether it is still running
     */
    private static boolean running = false;
    private static Display display;
    /**
     * Called by base in stand-alone help since it cannot run event loop
     */
    public static void run() {
        
        try {
            if (display == null)
                display = Display.getCurrent();
            if (display == null)
                display = new Display();
        } finally {
            started = true;
        }
        try {
            running = true;
            
///////////////////////////////////////////////////Aenderung-Start///////////////////////////////////////////////////////////////////////////////////////            
            
            XYZEmbeddedBrowserAdapter xyzEmbeddedBrowserAdapter = new XYZEmbeddedBrowserAdapter();
            BaseHelpSystem.getInstance().setBrowserInstance(xyzoEmbeddedBrowserAdapter);
            try {
                BaseHelpSystem.getHelpBrowser(true).displayURL(getBaseURL() + "index.jsp");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            
///////////////////////////////////////////////////Aenderung-Ende////////////////////////////////////////////////////////////////////////////////////////
            
            while (XYZHelpApplication.isRunning()) {
                try {
                    if (!display.readAndDispatch()) {
                        display.sleep();
                    }
                } catch (Throwable t) {
                    HelpBasePlugin.logError(t.getMessage(), t);
                }
            }
            display.dispose();
            display = null;
        } finally {
            running = false;
        }
    }
    public static void wakeup() {
        Display d = display;
        if (d != null)
            try {
                d.wake();
            } catch (Exception e) {
            }
    }
    /**
     * Blocks until the loop is started (Display created)
     */
    public static void waitFor() {
        while (!started && XYZHelpApplication.isRunning()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ie) {
            }
        }
    }
    /**
     * @return Returns if loop is running.
     */
    public static boolean isRunning() {
        return running;
    }
    
    private static String getBaseURL() {
        return "http://" //$NON-NLS-1$
                + WebappManager.getHost() + ":" //$NON-NLS-1$
                + WebappManager.getPort() + "/help/"; //$NON-NLS-1$
    }
}
```


```
package com.xyz.help.bootstrap;

import org.eclipse.help.ui.internal.browser.embedded.EmbeddedBrowser;
import org.eclipse.help.ui.internal.browser.embedded.EmbeddedBrowserAdapter;
import org.eclipse.swt.widgets.Display;

@SuppressWarnings("restriction")
public class XYZEmbeddedBrowserAdapter extends EmbeddedBrowserAdapter {
    private EmbeddedBrowser browser;
    // Thread to use in workbench mode on Windows
    private UIThread2 secondThread;
    class UIThread2 extends Thread {
        
        Display d;
        
        boolean runEventLoop = true;

        public UIThread2() {
            super();
            setDaemon(true);
            setName("Help Browser UI"); //$NON-NLS-1$
        }

        public void run() {
            d = new Display();
            while (runEventLoop) {
                if (!d.readAndDispatch()) {
                    d.sleep();
                }
            }
            d.dispose();
        }
        public Display getDisplay() {
            while (d == null && isAlive()) {
                try {
                    sleep(40);
                } catch (InterruptedException ie) {
                }
            }
            return d;
        }
        public void dispose() {
            runEventLoop = false;
        }
    }
    /**
     * Adapter constructor.
     */
    public XYZEmbeddedBrowserAdapter() {
        
    }
    public Display getBrowserDisplay() {
        return Display.getDefault();
    }

    public void browserClosed() {
        browser=null;
        if(secondThread!=null){
            secondThread.dispose();
            secondThread = null;
        }
        ///////////////////////////////////////////////////Aenderung-Start/////////////////////////////////////////////////////////////////////////////////////// 
        XYZHelpApplication.stopHelp();
       ///////////////////////////////////////////////////Aenderung-Ende/////////////////////////////////////////////////////////////////////////////////////// 
    }
    /*
     * @see IBrowser#displayURL(String)
     */
    public synchronized void displayURL(final String url) {
        close();
        if (getBrowserDisplay() == Display.getCurrent()) {
            uiDisplayURL(url);
        } else {
            getBrowserDisplay().asyncExec(new Runnable() {
                public void run() {
                    uiDisplayURL(url);
                }
            });
        }
    }
    /**
     * Must be run on UI thread
     * 
     * @param url
     */
    private void uiDisplayURL(final String url) {
        getBrowser().displayUrl(url);
    }

    /*
     * @see IBrowser#close()
     */
    public synchronized void close() {
        if (getBrowserDisplay() == Display.getCurrent()) {
            uiClose();
        } else {
            getBrowserDisplay().syncExec(new Runnable() {
                public void run() {
                    uiClose();
                }
            });
        }
    }
    /*
     * Must be run on UI thread
     */
    private void uiClose() {
        if (browser != null && !browser.isDisposed()){
            browser.close();
        }
        if(secondThread!=null){
            secondThread.dispose();
            secondThread=null;
        }
    }
    /**
     *  
     */
    private EmbeddedBrowser getBrowser() {
        if (browser == null || browser.isDisposed()) {
            browser = new EmbeddedBrowser();
            browser.addCloseListener(this);
        }
        return browser;
    }
    /*
     * @see IBrowser#isCloseSupported()
     */
    public boolean isCloseSupported() {
        return true;
    }
    /*
     * @see IBrowser#isSetLocationSupported()
     */
    public boolean isSetLocationSupported() {
        return true;
    }
    /*
     * @see IBrowser#isSetSizeSupported()
     */
    public boolean isSetSizeSupported() {
        return true;
    }
    /*
     * @see IBrowser#setLocation(int, int)
     */
    public synchronized void setLocation(final int x, final int y) {
        if (getBrowserDisplay() == Display.getCurrent()) {
            uiSetLocation(x, y);
        } else {
            getBrowserDisplay().asyncExec(new Runnable() {
                public void run() {
                    uiSetLocation(x, y);
                }
            });
        }
    }
    /*
     * Must be run on UI thread
     */
    private void uiSetLocation(int x, int y) {
        getBrowser().setLocation(x, y);
    }
    /*
     * @see IBrowser#setSize(int, int)
     */
    public synchronized void setSize(final int width, final int height) {
        if (getBrowserDisplay() == Display.getCurrent()) {
            uiSetSize(width, height);
        } else {
            getBrowserDisplay().asyncExec(new Runnable() {
                public void run() {
                    uiSetSize(width, height);
                }
            });
        }
    }
    /*
     * Must be run on UI thread
     */
    private void uiSetSize(int width, int height) {
        getBrowser().setSize(width, height);
    }
}
```

Fuer jeden Verbesserungsvorschlag bin ich jederzeit Ohr!


----------



## namenlos123 (22. Jun 2010)

Achso... verspaetet aber noch daran gedacht...

Danke Wildcard fuer deine Beitraege. Hat mir dieses Thema verstaendlicher gemacht.:toll:


Gruss,
namenlos.


----------



## namenlos123 (29. Jun 2010)

Das Thema kann geschlossen werden, falls keiner noch Fragen oder Anmerkungen zu Eclipse Standalone Help hat.


----------

