Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [e4-dev] Dynamic Eclipse 4 with Clojure language


2013/12/12 Lars Vogel <lars.vogel@xxxxxxxxx>

In Eclipse Luna the service has been extend to find all elements including Handlers, etc

That's a good news!

So this solves the first half of the problem: finding elements.

The other half is being able to remove some of these elements from the Application Model.

Currently what I do is:
- for elements that implement MUIElement, there's a .getParent() method, and on the parent (which is a MUIElementContainer) I can call .getChildren().remove(element)
- for specific elements such as MCommand, MHandler, MKeybinding, well, since I'm in Kepler, I already have their container list, and I also call .remove(element). BUT I would not have been able to call mcommand.getParent() since MCommand is not a MUIElement, but just a MApplicationElement, where (unless I'm mistaken) there's no .getParent() kind of method.

Is there a solution for this second hald of my problem in Luna ?

Cheers,

-- 
Laurent



 
Am 12.12.2013 14:48 schrieb "Laurent PETIT" <laurent.petit@xxxxxxxxx>:

== Status Update

=== Dynamic Classpath handling

For Counterclockwise User plugins, the mid/long-term goal is to switch to real dynamically created bundles (not as jars, just as exploded bundles), with dynamic creation of MANIFEST.MF if missing.

This will be especially necessary when users will want to use dependencies that are not already available through ccw.core bundle's classpath.

=== Cleanup of the Application Model

tl;dr: is there somewhere a global utility method to remove any kind of MApplicationElement (MUIElement, MCommand, MHandler, MWindow, etc.) from an MApplication by tag and presence/absence of transient keys?

When user plugins are launched, all the Model Elements they add to the Application Model are appropriately tagged with "ccw-<user-plugin-id>", and a transient "launch key".

At the end of the launch of user plugins, all the Application Model Elements that have "ccw-<user-plugin-id>" but not the right transient "launch key" are removed from the Model.

My question is: how to write the code to find & remove arbitrary elements from the model ?

- The EModelService provides a method to find MUIElements, which can then be removed by calling element.getParent().getChildren().remove(element), right ?

- But what about MCommands, MHandlers, MKeybindings, MWindows, and probably many other special cases I'm still not aware of?
Currently I wrote specific code for MCommands, MHandlers, MKeybindings.
And now I see that MWindows can also contain MHandlers, so my code for removing MHandlers is incomplete ....


Thanks in advance,

-- 
Laurent Petit















2013/12/5 Laurent PETIT <laurent.petit@xxxxxxxxx>
Hello wim,

Thanks for the tip, I've narrowed down a little bit more the problem.
Seems that I was partially wrong in my previous email: the problem
*is* related to key-bindings, after all.
More precisely, it appears when/if as a user I try to display the Keys
preference page, find my "Hello world" command:

- first weird thing: right after doing that, I don't see the key
sequence I've defined programatically, even tho it already works.
- thus as a user I try to re-enter the key sequence, and save.

After the next startup, the exception appears again: probably because
there are 2 key-bindings defined for the same [ key-sequence / context
/ command ] tuple ? (one programmatically, one by the user)



2013/12/5 Wim Jongman <wim.jongman@xxxxxxxxx>:
> I recently saw this exception. It appeared to be caused by having two
> elements with the same id in the model.
>
> Cheers,
>
> Wim
>
>
> On Thu, Dec 5, 2013 at 9:52 PM, Laurent PETIT <laurent.petit@xxxxxxxxx>
> wrote:
>>
>> Current status:
>>
>> I adopted the EventBroker + APP_STARTUP_COMPLETE option: In my Model
>> Processor class, I just register for the APP_STARTUP_COMPLETE event
>> and then in the callback function I dynamically modify the model like
>> this:
>>
>> ;; file ~/.ccw/script.clj
>> ;; boring namespace declaration and imports omitted
>> (defn greet [context]
>>   (info-dialog "Hello world" "This popup provided to you from a user
>> script"))
>>
>> (defcommand greeter "Hello from CCW")
>>
>> (defhandler greeter greet)
>>
>> (defkeybinding greeter "Ctrl+Alt+Y")
>>
>> The callback triggered from the APP_STARTUP_COMPLETE event localizes
>> user scripts in ~/.ccw and executes them.
>>
>> The defcommand / defhandler / defkeybinding try as much as possible to
>> reuse existing commands/handlers/keybindings in the Model based on
>> identifiers (command, handler) or field values (keybinding).
>>
>> The tag "ccw" is added to every command/handler/keybinding object
>> merged. There's also a randomUUID set as the value of the key
>> "ccw/load-key" in the Transient State.
>>
>> Once the user script has been loaded, all
>> commands/handlers/keybindings in the Application Model with tag "ccw"
>> are gathered. Those that do not have a transient "ccw/load-key" key,
>> or a transient "ccw/load-key" key with the wrong value are removed
>> from the Application Model (the latter case is for being able to
>> live-reload the user scripts while developing, and still keeping the
>> Application Model clean).
>>
>> Overall, works already quite well.
>>
>> I thought this was the time to get some feedback from e4 experts on
>> what I already did.
>>
>> I also have a question: I keep getting an exception stack trace, even
>> in the simplest scenario, while the user script starts.
>>
>> I the simplest case, it happens when I only have (defcommand ...) and
>> (defhandler ...), even on a cleaned workspace + -clearPersistedState
>> option set.
>>
>> I don't know what it means, and my mind isn't clear as to how I could
>> investigate more:
>>
>> !ENTRY org.eclipse.equinox.event 4 0 2013-12-05 21:37:30.658
>>
>> !MESSAGE Exception while dispatching event
>> org.osgi.service.event.Event
>> [topic=org/eclipse/e4/ui/model/application/Contribution/object/SET] to
>> handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@7e11b954
>>
>> !STACK 0
>>
>> java.lang.ClassCastException:
>> org.eclipse.e4.ui.model.application.commands.impl.HandlerImpl cannot
>> be cast to org.eclipse.e4.ui.model.application.ui.MUIElement
>>
>> at
>> org.eclipse.ui.internal.WorkbenchPage$5.handleEvent(WorkbenchPage.java:4949)
>>
>> at
>> org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:41)
>>
>> at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:180)
>>
>> at
>> org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)
>>
>> at org.eclipse.swt.widgets.Display.syncExec(Display.java:4650)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:205)
>>
>> at
>> org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:38)
>>
>> at
>> org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:197)
>>
>> at
>> org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197)
>>
>> at
>> org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1)
>>
>> at
>> org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
>>
>> at
>> org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
>>
>> at
>> org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135)
>>
>> at
>> org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78)
>>
>> at
>> org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39)
>>
>> at
>> org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:80)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:58)
>>
>> at
>> org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374)
>>
>> at
>> org.eclipse.e4.ui.model.application.impl.ContributionImpl.setObject(ContributionImpl.java:131)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon.processActiveHandler(HandlerProcessingAddon.java:158)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon.access$0(HandlerProcessingAddon.java:151)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon$1.handleEvent(HandlerProcessingAddon.java:80)
>>
>> at
>> org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:41)
>>
>> at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:180)
>>
>> at
>> org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)
>>
>> at org.eclipse.swt.widgets.Display.syncExec(Display.java:4650)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:205)
>>
>> at
>> org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:38)
>>
>> at
>> org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:197)
>>
>> at
>> org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197)
>>
>> at
>> org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1)
>>
>> at
>> org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
>>
>> at
>> org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
>>
>> at
>> org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135)
>>
>> at
>> org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78)
>>
>> at
>> org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39)
>>
>> at
>> org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:80)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:58)
>>
>> at
>> org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374)
>>
>> at
>> org.eclipse.emf.ecore.util.EcoreEList.dispatchNotification(EcoreEList.java:249)
>>
>> at
>> org.eclipse.emf.common.notify.impl.NotifyingListImpl.addUnique(NotifyingListImpl.java:356)
>>
>> at org.eclipse.emf.common.util.AbstractEList.add(AbstractEList.java:339)
>>
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>
>> at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>
>> at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>
>> at java.lang.reflect.Method.invoke(Method.java:601)
>>
>> at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
>>
>> at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
>>
>> at ccw.util.e4.model$add_handler_BANG_.invoke(model.clj:653)
>>
>> at ccw.util.e4.model$merge_handler_BANG_.invoke(model.clj:800)
>>
>> at lein_script_test$fn__2851.invoke(script.clj:11)
>>
>> at clojure.lang.AFn.applyToHelper(AFn.java:159)
>>
>> at clojure.lang.AFn.applyTo(AFn.java:151)
>>
>> at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3458)
>>
>> at clojure.lang.Compiler$DefExpr.eval(Compiler.java:408)
>>
>> at clojure.lang.Compiler.eval(Compiler.java:6624)
>>
>> at clojure.lang.Compiler.load(Compiler.java:7064)
>>
>> at clojure.lang.Compiler.loadFile(Compiler.java:7020)
>>
>> at clojure.lang.RT$3.invoke(RT.java:318)
>>
>> at
>> ccw.core.user_plugins$start_user_plugins$fn__2833.invoke(user_plugins.clj:70)
>>
>> at ccw.core.user_plugins$start_user_plugins.invoke(user_plugins.clj:69)
>>
>> at clojure.lang.Var.invoke(Var.java:411)
>>
>> at ccw.util.ClojureUtils.invoke(ClojureUtils.java:28)
>>
>> at ccw.util.ClojureInvoker._(ClojureInvoker.java:18)
>>
>> at
>> ccw.core.Eclipse4ModelProcessor$1.handleEvent(Eclipse4ModelProcessor.java:45)
>>
>> at
>> org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:41)
>>
>> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
>>
>> at
>> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
>>
>> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3976)
>>
>> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3653)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1113)
>>
>> at
>> org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:138)
>>
>> at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:610)
>>
>> at
>> org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
>>
>> at
>> org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567)
>>
>> at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
>>
>> at
>> org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
>>
>> at
>> org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
>>
>> at
>> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
>>
>> at
>> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
>>
>> at
>> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
>>
>> at
>> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)
>>
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>
>> at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>
>> at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>
>> at java.lang.reflect.Method.invoke(Method.java:601)
>>
>> at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
>>
>> at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
>>
>> at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
>>
>> at org.eclipse.equinox.launcher.Main.main(Main.java:1426)
>>
>>
>>
>>
>>
>>
>>
>> 2013/12/2 Laurent PETIT <laurent.petit@xxxxxxxxx>:
>> > Hey Paul,
>> >
>> > 2013/12/2 Paul Webster <pwebster@xxxxxxxxxxxxxxxxxxx>:
>> >> Hi Laurent,
>> >>
>> >> On Mon, Dec 2, 2013 at 8:04 AM, Laurent PETIT <laurent.petit@xxxxxxxxx>
>> >> wrote:
>> >>>
>> >>> I have considered it, not tried yet.
>> >>>
>> >>> So far, I have spotted in past discussions on the subject the
>> >>> following possibilities:
>> >>>
>> >>> 1/ EventBroker + APP_STARTUP_COMPLETE event => when to register to the
>> >>> EventBroker in the context of Eclipse the IDE? By doing it in my
>> >>> current Model Processor hook ?
>> >>
>> >>
>> >> Yes, we often use model processors to register for events (especially
>> >> related to model changes) for the application going forward.  This is
>> >> the
>> >> Eclipse4 compatible approach.
>> >
>> > So I'll use this method, even if, as you pointed out, I will continue
>> > to live in a cross world between 3.x and 4.x APIs, since I won't be
>> > able to migrate all my code at once (and also I depend on so many
>> > things that are still stuck in the 3.x world, I guess ...)
>> >
>> >>
>> >>>
>> >>> 2/ Extend org.eclipse.ui.startup ? I have read that I am guaranteed
>> >>> that when my earlyStartup() method is called the Workbench is already
>> >>> totaly operational. But then how to get the MApplication instance?
>> >>> Currently I'm doing
>> >>>
>> >>>
>> >>> PlatformUI.getWorkbench().getService(IEclipseContext.class).get(MApplication.class).
>> >>
>> >>
>> >> If you use org.eclipse.ui.startup, you've picked the right pattern.
>> >> This is
>> >> based on 3.x (o.e.ui.startup is not part of Eclipse4) but if you need
>> >> access
>> >> to things that need the Workbench, then you are tied to 3.x anyway.
>> >>
>> >>>
>> >>> 3/ Just use asyncExec on the display. But how to get the display
>> >>> instance?
>> >>
>> >>
>> >> If you are running in the IDE (which has the Workbench) this is the
>> >> hardest
>> >> thing to get correct.  Calling Display.getDefault() can instantiate a
>> >> display on the incorrect thread and cause problems.  We use
>> >> org.eclipse.ui.IWorkbench.getDisplay() but that's then tied to 1)
>> >> running
>> >> against the 3.x Workbench and 2) waiting until the workbench is up,
>> >> which
>> >> happens after the model processor stuff is called.
>> >>
>> >>
>> >> Later,
>> >> Paul
>> >>
>> >>
>> >>
>> >> --
>> >> Paul Webster
>> >> Hi floor.  Make me a sammich! - GIR
>> >>
>> >> _______________________________________________
>> >> e4-dev mailing list
>> >> e4-dev@xxxxxxxxxxx
>> >> https://dev.eclipse.org/mailman/listinfo/e4-dev
>> >>
>> _______________________________________________
>> e4-dev mailing list
>> e4-dev@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/e4-dev
>
>
>
> _______________________________________________
> e4-dev mailing list
> e4-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/e4-dev
>


_______________________________________________
e4-dev mailing list
e4-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/e4-dev


_______________________________________________
e4-dev mailing list
e4-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/e4-dev



Back to the top