Anonymous
Not applicable

AppCenter-Skript liefert statt Elementen jxbrowser.Proxy

Jump to solution

Hallo FS-Community,

langsam bin ich ziemlich am verzweifeln. Wir versuchen hier nun schon fast den ganzen Tag eine einfachste (!!!) AppCenter-Application zu erstellen. Hierbei sollen lediglich alle Teaser der zeit.de-Startseite mit einem Mouseover hinterlegt werden.

Das Problem ist jedoch, dass ich mich nicht durch den DOM-Baum bis zu den entsprechenden Elementen hangeln kann, da JEDES Element, dass ich vom BrowserHandler zurückbekomme ein class de.espirit.firstspirit.client.gui.applications.jxbrowser.Proxy-Objekt ist, mit dem man aber auch mal gerade gar nichts anfangen kann ...

Folgendes Skript verwenden wir (vom Wikipedia-Showcase geklaut und leicht abgewandelt):

import de.espirit.firstspirit.client.gui.applications.ApplicationService;

import de.espirit.firstspirit.client.gui.applications.browser.BrowserApplicationConfiguration;

import de.espirit.firstspirit.client.gui.applications.browser.EngineType;

import de.espirit.firstspirit.client.gui.applications.browser.BrowserApplication;

import de.espirit.firstspirit.access.ServicesBroker;

import de.espirit.firstspirit.agency.StoreAgent;

import de.espirit.firstspirit.agency.ResolutionAgent;

import de.espirit.firstspirit.access.store.Store;

import de.espirit.firstspirit.access.store.mediastore.Media;

import de.espirit.common.function.UnaryProcedure;

import javax.swing.ImageIcon;

import java.awt.datatransfer.DataFlavor;

import javax.swing.Action;

import de.espirit.firstspirit.agency.TransferAgent;

import de.espirit.common.crypto.Base64;

/* --- ElementDecorator --- */

onRegister(element, node) {

          element.setAttribute("onmouseout", "this.style.backgroundColor='';");

          element.setAttribute("onmouseover", "this.style.backgroundColor='#EAB9CC';");

}

/* --- Browser Listener --- */

onDocumentComplete(String url) {

          nodeHandlerBuilder = browserApp.createNodeHandlerBuilder();

          nodeHandlerBuilder.setElementDecorator(this);

          doc = browserApp.getCurrentDocument(); //ist laut Logging bereits ein $Proxy88

          mainElement = doc.getElementById("main");

          nodeHandler = nodeHandlerBuilder.bind();

          if (mainElement != null) {

    childList = mainElement.getChildNodes();

    for(int i = 0; i < childList.getLength(); i++) {

      nodeHandler.register(childList.item(i), url); //jedes Item ist ein $Proxy93 und kann damit nicht an die register(Element, Node)-Methode weitergegeben werden...

    }

          }

}

// fall back method for not yet implemented calls

invoke(method, args) {

          buf = new StringBuilder();

          for (int i = 0; i < args.length; i++) {

                    buf.append(args[i]).append("(").append(args[i].getClass().getName()).append(")");

                    buf.append(",");

          }

          context.logDebug("not implemented yet: '" + method + "' args=" + args.length + " [" + buf.toString() + "]");

}

/* ============================ */

/* ========== Script ========== */

/* ============================ */

services = context.requireSpecialist(ServicesBroker.TYPE);

appService = services.getService(ApplicationService.class);

APP_IDENT = "ZEIT_APPCENTER";

// search url combined with text field value passed via FS_BUTTON in sectiontemplate: "Zeit_test"

url = "http://www.zeit.de/index";

// is there already a wikipedia search tab

existing = appService.getApplication(BrowserApplication.TYPE, APP_IDENT);

if (existing != null && !existing.isClosed()) {

          // reuse existing tab

          existing.setSelected();

          existing.getApplication().openUrl(url);

} else {

          // browser configuration

          configuration = BrowserApplicationConfiguration.GENERATOR.invoke().

                    //icon(icon).

                    identifier(APP_IDENT).

                    title("Zeit App");

          appTab = appService.openApplication(BrowserApplication.TYPE, configuration);

          browserApp = appTab.getApplication();

          browserApp.addBrowserListener(this);

          browserApp.openUrl(url);

}

Was mache ich oder was läuft hier falsch? Warum kann ich nicht so etwas simples mittels Skript erledigen? Ich würde hierfür nicht unbedingt so gern ein eigenes Modul schreiben müssen. Und gibt es eine Möglichkeit Skript irgendwie zu debuggen? Es ist ein Krux sich selbst Error-Logs einzubauen, nur um dann zu merken, dass ein Skript in irgendeiner alten Version von vor 10min gestartet wurde obwohl es gespeichert, zurückgegeben und mind. 2min mit F5 bearbeitet wurde.

Viele Grüße aus Hamburg

0 Kudos
1 Solution

Accepted Solutions
gockel
Crownpeak employee

if (mainElement != null) {

    childList = mainElement.getChildNodes();

    for(int i = 0; i < childList.getLength(); i++) {

      nodeHandler.register(childList.item(i), url); //jedes Item ist ein $Proxy93 und kann damit nicht an die register(Element, Node)-Methode weitergegeben werden...

    }

}

Das Problem ist hier nicht, dass dort ein Proxy von uns drumliegt, sondern dass sie ungeprüft Objekte vom Typ org.w3c.dom.Node an eine Methode (#register) weitergeben, die nur org.w3c.dom.Element als Parameter erlaubt.

In Java hätten sie dabei einen Compile-Error erhalten. In Beanshell natürlich nicht.

So sollte es funktionieren:

if (mainElement != null) {

    childList = mainElement.getChildNodes();  // liefert NodeList zurück

    for(int i = 0; i < childList.getLength(); i++) {

        childNode = childList.item(i);     // liefert Node zurück

        if (childNode.getNodeType() == Node.ELEMENT_NODE) {

          nodeHandler.register(childNode, url);

      }

    }

}

View solution in original post

0 Kudos
4 Replies
gockel
Crownpeak employee

Hallo,

bitte mal die allgemeinen Zusatzinfos posten: siehe auch Demo Posting

und natürlich die für den Anwendungsfall spezifischen Infos:

* welcher Browser ist für das interne Preview eingestellt: Firefox oder Internet Explorer

Gockel

0 Kudos
Anonymous
Not applicable

Hallo Sebastian,

für die interne Vorschau verwenden wir die Firefox-Engine.

Hier die Zusatzinfos (ab jetzt häng ich die an meine Postings mit dran):

FirstSpirit Client 4.2.461.48921

Server: localhost:8000 (HTTP)

Projekt: AppCenter Showcase

Benutzer: Admin

Version Server: 4.2.461.48921

Lizensiert für: Acando (Entwicklungslizenz)

Java Version: 1.6.0_31 32bit Sun Microsystems Inc.

Betriebssystem: Windows 7 6.1 x86

Und der Stacktrace des Fehlers:

Admin (Admin), session: 5919539207727560953, project: 4638, ip: 172.27.24.125

(de.espirit.firstspirit.client.gui.applications.browser.BrowserApplicationImpl): error handling browser event. browser listener='this' reference (XThis) to Bsh object: NameSpace: BeanshellExecutable (bsh.NameSpace@14a3f84)

implements: de.espirit.firstspirit.client.gui.applications.browser.BrowserListener - java.lang.reflect.UndeclaredThrowableException

FSVersion=4.2.461.48921#1905;JDK=1.6.0_31 32bit Sun Microsystems Inc.;OS=Windows 7 6.1 x86;Date=21.03.2012 10:44:47

java.lang.reflect.UndeclaredThrowableException

     at $Proxy46.onDocumentComplete(Unknown Source)

     at de.espirit.firstspirit.client.gui.applications.browser.BrowserApplicationImpl$7.invoke(BrowserApplicationImpl.java:561)

     at de.espirit.firstspirit.client.gui.applications.browser.BrowserApplicationImpl$7.invoke(BrowserApplicationImpl.java:560)

     at de.espirit.firstspirit.client.gui.applications.browser.BrowserApplicationImpl$4.run(BrowserApplicationImpl.java:440)

     at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

     at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)

     at java.util.concurrent.FutureTask.run(Unknown Source)

     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)

     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

     at java.lang.Thread.run(Unknown Source)

Caused by: Error in method invocation: Method register( de.espirit.firstspirit.client.gui.applications.jxbrowser.$Proxy104, java.lang.String ) not found in class'de.espirit.firstspirit.client.gui.applications.jxbrowser.BrowserNodeHandlerImpl' : at Line: 35 : in file: inline evaluation of: ``__execute(namespace) { setNameSpace(namespace); import de.espirit.firstspirit.cl . . . '' : nodeHandler .register ( childList .item ( i ) , url )

     at bsh.BSHMethodInvocation.eval(Unknown Source)

     at bsh.BSHPrimaryExpression.eval(Unknown Source)

     at bsh.BSHPrimaryExpression.eval(Unknown Source)

     at bsh.BSHBlock.evalBlock(Unknown Source)

     at bsh.BSHBlock.eval(Unknown Source)

     at bsh.BSHBlock.eval(Unknown Source)

     at bsh.BSHForStatement.eval(Unknown Source)

     at bsh.BSHBlock.evalBlock(Unknown Source)

     at bsh.BSHBlock.eval(Unknown Source)

     at bsh.BSHBlock.eval(Unknown Source)

     at bsh.BSHIfStatement.eval(Unknown Source)

     at bsh.BSHBlock.evalBlock(Unknown Source)

     at bsh.BSHBlock.eval(Unknown Source)

     at bsh.BshMethod.invokeImpl(Unknown Source)

     at bsh.BshMethod.invoke(Unknown Source)

     at bsh.BshMethod.invoke(Unknown Source)

     at bsh.This.invokeMethod(Unknown Source)

     at bsh.This.invokeMethod(Unknown Source)

     at bsh.XThis$Handler.invokeImpl(Unknown Source)

     at bsh.XThis$Handler.invoke(Unknown Source)

     ... 10 more

Der Fehler tritt in Zeile 35 des Skripts auf, diese Zeile ist genau die hier:

nodeHandler.register(childList.item(i), url);

Viele Grüße

0 Kudos
gockel
Crownpeak employee

if (mainElement != null) {

    childList = mainElement.getChildNodes();

    for(int i = 0; i < childList.getLength(); i++) {

      nodeHandler.register(childList.item(i), url); //jedes Item ist ein $Proxy93 und kann damit nicht an die register(Element, Node)-Methode weitergegeben werden...

    }

}

Das Problem ist hier nicht, dass dort ein Proxy von uns drumliegt, sondern dass sie ungeprüft Objekte vom Typ org.w3c.dom.Node an eine Methode (#register) weitergeben, die nur org.w3c.dom.Element als Parameter erlaubt.

In Java hätten sie dabei einen Compile-Error erhalten. In Beanshell natürlich nicht.

So sollte es funktionieren:

if (mainElement != null) {

    childList = mainElement.getChildNodes();  // liefert NodeList zurück

    for(int i = 0; i < childList.getLength(); i++) {

        childNode = childList.item(i);     // liefert Node zurück

        if (childNode.getNodeType() == Node.ELEMENT_NODE) {

          nodeHandler.register(childNode, url);

      }

    }

}

0 Kudos
Anonymous
Not applicable

Hallo Sebastian,

vielen Dank für die schnelle Antwort! So funktioniert es tatsächlich! Den Import von org.w3c.dem.Node musste ich dann noch ergänzen.

Viele Grüße,

Nils

0 Kudos