Eclipse Plugin development showing and hiding menuContribution when opening and closing perspective - menu

I am developing my Eclipse Plugin using E4 2020-09 version. I created a Perspective and a menuContribution using Model Fragments. I have searched several tutorials but I have not seen any that showing how to make a menuContribution appear/disappear when opening/closing a Perspective in E4 during development. What I found was these examples: https://github.com/vogellacompany/codeexamples-eclipse but this function is implemented for E3 and I want to implement it in E4.
Can you give me some hints/advices about this technique and how it is called or where to start with it?
Thanks and best regards.

You can do this in the 'Visible-When Expression' for the menu items.
Set the expression to be 'ImperativeExpression'. And create a class to handle the expression. This class just has a single method annotated with #Evaluate which is called each time the menu item might be displayed:
#Evaluate
public boolean evaluate(EModelService modelService, .... other parameters)
{
// TODO determine if menu item should be visible
}
This class can then use the getActivePerspective method of EModelService to check if the menu item should be visible.

449,
Thank you for you answer, I finally made it according to your instruction. I will leave my reference code here in case there are people asking about this:
Create MenuContributionsHandler class
package com.catto.ide.dev.handlers;
import javax.inject.Inject;
import org.eclipse.e4.core.di.annotations.Evaluate;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
public class MenuContributionsHandler
{
#Inject MWindow window;
#Evaluate
public boolean evaluate(EModelService modelService)
{
// TODO determine if menu item should be visible (return true)
MPerspective currentPerspective = modelService.getActivePerspective(window);
if (null != currentPerspective)
{
return currentPerspective.getLabel().equals("SnowCatto");
}
return false;
}
}
Add this class to the Imperative Expression to MenuContribution Class URI.
Best regards.

Related

Haxe - Why can I not access a child's attribute without getting an error that the parent does not have the given attribute?

I've recently been getting into Haxe and just started to use HaxeFlixel to load a Tiled .TMX file.
I am creating a TiledMap object and passing it the TMX file path, then I want to iterate over the layers in that object to add them to the game scene. However when I try to access .tileArray (which is a property of TiledTileLayer) I get the following error :-
flixel.addons.editors.tiled.TiledLayer has no field tileArray
Here is the code:
package;
import flixel.FlxState;
import flixel.tile.FlxTilemap;
import flixel.addons.editors.tiled.TiledMap;
import openfl.Assets;
class PlayState extends FlxState
{
private var _tiled_map:TiledMap;
override public function create():Void
{
_tiled_map = new TiledMap("assets/data/Map1.tmx");
for(layer in _tiled_map.layers){
var layerData:Array<Int> = layer.tileArray;
}
super.create();
}
override public function update(elapsed:Float):Void
{
super.update(elapsed);
}
}
I've found the following example - http://coinflipstudios.com/devblog/?p=182 which seems to work fine for people.
So I wanted to check whether the layer object was a TiledTileLayer as it should be, or TiledLayer, with the following:
trace(Type.typeof(layer));
Which sure enough yields:
PlayState.hx:24: TClass([class TiledTileLayer])
So if it is a TiledTileLayer which has the field tileArray why is it moaning?
I had a look at the source code (https://github.com/HaxeFlixel/flixel-addons/blob/dev/flixel/addons/editors/tiled/TiledMap.hx#L135) and TiledTileLayer inherits from TiledLayer. Layers is an array of type TiledLayer, so I think this is why it is moaning. I can clearly see that the array is storing child objects of TiledLayer, but as soon as I access any props/methods of those children, it complains that the parent does not have that field? Very confusing!
To run I'm using this command: C:\HaxeToolkit\haxe\haxelib.exe run lime test flash -debug -Dfdb
Thank you!
So if it is a TiledTileLayer which has the field tileArray why is it moaning?
It may be a TiledTileLayer in this case, but that may not always be the case. layers is an Array<TileLayer> after all, so it could be a TiledObjectLayer or a TiledImageLayer as well (which don't have a tileArray field). This can nicely be seen in the code you linked. The concrete type can only be known at runtime, but the error you get happens at compile-time.
If you know for sure there won't be any object or image layers, you can just cast it to a TiledTileLayer. However, just to be safe, it's good practice to check the type beforehand anyway:
for (layer in _tiled_map.layers) {
if (Std.is(layer, TiledTileLayer)) {
var tileLayer:TiledTileLayer = cast layer;
var layerData:Array<Int> = tileLayer.tileArray;
}
}
It works without this for the tutorial you linked because it was made for an older version of flixel-addons.

change label value using value stored at session

i have two jsf pages (home.jsf and employees.jsf) ,
home page has a button that navigates to employees page,
while navigating i store value in session scope
at (Managed bean)
public void putSessionAL(ActionEvent actionEvent) {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("key","value");
}
public String navigate() {
return "employees";
}
i want to change Label at employees viewObject from UIHints tab depending on value stored at session using the following groovy expression
adf.context.sessionScope.key
and changed trustMode to trusted but it fires the following exception
oracle.jbo.script.ExprScriptException: JBO-29114 ADFContext is not setup to process messages for this exception. Use the exception stack trace and error code to investigate the root cause of this exception. Root cause error code is JBO-25188. Error message parameters are {0=Employees.FirstName, 1=, 2=oracle.jbo.script.ExprSecurityException}
at oracle.jbo.script.ExprScriptException.throwException(ExprScriptException.java:316)
at oracle.jbo.script.ExprScriptException.throwExceptionWithExprDef(ExprScriptException.java:387)
at oracle.jbo.ExprEval.processScriptException(ExprEval.java:599)
at oracle.jbo.ExprEval.doEvaluate(ExprEval.java:697)
at oracle.jbo.ExprEval.evaluate(ExprEval.java:508)
at oracle.jbo.ExprEval.evaluate(ExprEval.java:487)
at oracle.jbo.common.NamedObjectImpl.resolvePropertyRaw(NamedObjectImpl.java:680)
at oracle.jbo.server.DefObject.resolvePropertyRaw(DefObject.java:366)
One way to do it at the VO UIHint attribute label level will be programmaticaly by doing as follow :
In your VO go to the java tab and add the RowImpl java class
In the VORowImpl Add the following function
public String getMySessionLabel() {
return (String)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("key");
}
In the Label add the following EL expression :
adf.object.getMySessionLabel()
This technique allow you more control than pure EL, if you want to do more than getting from session for example. In your case pure EL, as you did, should work as well. (Would need to check what is wrong with yours, maybe just missing the
#{adf.context.sessionScope.key}
If you attempt to get your label from a method in viewRowImpl. So this will be executed at least once for each row. I think this solution isn't fit for your case.
anyway ADF as a framework added strong policy and validations in EL in general and especially in version 12.2.x.
The solution for you case as following:
Create new class in model layer which extends oracle.jbo.script.ExprSecurityPolicy class
Override checkProperty method.
#Override
public boolean checkProperty(Object object, String string, Boolean b) {
if (object.getClass().getName().equals("oracle.adf.share.http.ServletADFContext") && string.equals("sessionScope")) {
return true;
}
return super.checkProperty(object, string, b);
}
Open adf-config.xml source and in startup tag set your class ExprSecurityPolicy property.
like:
<startup ExprSecurityPolicy="model.CustomExprSecurityPolicy">

griffon javafx-groovy and fxml?

I tried the samples given in github griffon-master, also I tried the samples of the guide.
I would like to use javafx and groovy.
I would like to use fxml - thought of a scenario as that: fxml to set the stage, and for changes, use the groovy (set adjustment)
It seems that is not possible. I can use ("make it run"): javafx-java, read an fxml (with loadFromFXML), and the bindings are working. If using javafx-groovy, I can read an fxml, but with the javafx-class Loader (load), and bindings are not working (or it seems so).
Is it not possible at this moment, to use javafx-groovy and read-in fxml (via loadfromfxml)?
Could you post some sample code? Here's one example that makes use of the fxml node form GroovyFX
package org.example
import griffon.core.artifact.GriffonView
import griffon.metadata.ArtifactProviderFor
import javafx.scene.control.Tab
import org.codehaus.griffon.runtime.javafx.artifact.AbstractJavaFXGriffonView
#ArtifactProviderFor(GriffonView)
class Tab4View extends AbstractJavaFXGriffonView {
FactoryBuilderSupport builder
SampleController controller
SampleModel model
private AppView parentView
void initUI() {
builder.with {
content = builder.fxml(resource('/org/example/tab4.fxml')) {
inputLabel.text = application.messageSource.getMessage('name.label')
bean(input, text: bind(model.inputProperty()))
bean(output, text: bind(model.outputProperty()))
}
}
connectActions(builder.content, controller)
Tab tab = new Tab('Hybrid')
tab.content = builder.content
parentView.tabPane.tabs.add(tab)
}
}
This can be done. The trick is to make your Controller actions adhere to a stringent set of rules. The tldr is to make sure they return void.
Good:
def void save() {
Bad:
def save() {
The reason is found in the reflective analysis the Griffon framework uses to create its list of action targets. This list is generated in DefaultGriffonControllerClass.getActionNames(), which requires that:
Actions are subject to the following rules in order to be considered as such:
must have public (Java) or default (Groovy) visibility modifier.
name does not match an event handler, i.e, it does not begin with on.
must pass {code GriffonClassUtils.isPlainMethod()} if it's a method.
must have void as return type if it's a method.
value must be a closure (including curried method pointers) if it's a property.
The criteria defined in GriffonClassUtils.isPlainMethod() are as follows:
isInstanceMethod(method)
! isBasicMethod(method)
! isGroovyInjectedMethod(method)
! isThreadingMethod(method)
! isArtifactMethod(method)
! isMvcMethod(method)
! isServiceMethod(method)
! isEventPublisherMethod(method)
! isObservableMethod(method)
! isResourceHandlerMethod(method)
! isGetterMethod(method)
! isSetterMethod(method)
! isContributionMethod(method)
The list of action target names is subsequently used by AbstractActionManager:
#Nullable
private static Method findActionAsMethod(#Nonnull GriffonController controller, #Nonnull String actionName) {
for (Method method : controller.getClass().getMethods()) {
if (actionName.equals(method.getName()) &&
isPublic(method.getModifiers()) &&
!isStatic(method.getModifiers()) &&
method.getReturnType() == Void.TYPE) {
return method;
}
}
return null;
}

How to check you have landed on one of several pages in Geb

I'm new to Groovy and testing a website with reasonably complex workflows using Geb/Cucumber.
I have a set of product pages represented by page classes Prod1Page, Prod2Page and Prod3Page. They share certain characteristics that can be tested by the same code.
I want to write a ProductPage page class along the lines of:
class ProductPage extends Page {
...
static at = {...}
...
}
so that
Given(~/.../) {
...
at ProductPage
...
}
would pass if any of the following were true:
at Prod1Page
at Prod2Page
at Prod3Page
In case it's not clear my goal is to avoid duplicating the details of Prod[1-3]Page classes somewhere else.
Thanks for any insights,
Nick
In the ProductPage's at checker just assert that the common HTML elements between all Prod#Pages are available. For example, if all ProdPages have a <div id="productContainer"> element then you can put the following in your ProductPage class:
class ProductPage extends Page{
static at = { $("#productContainer").displayed }
...
}
Now in your test you can call at ProductPage and it will assert true if that common element is currently available on the WebDriver's DOM; and you will know that you are on one of the ProdPages.

DSL Add Root Element to Serialization

I am looking for help to achieve the following
The Diagram represents a car, users can add engine and colour
when I view the XML it looks like this:
<Car>
<Engine>BigEngine</Engine>
<Colour>Pink</Colour>
</Car>
What I would like to do is to wrap the car inside 'vehicle', i.e
<Vehicle>
<Car>
<Engine>BigEngine</Engine>
<Colour>Pink</Colour>
</Car>
</Vehicle>
I am not sure of the best way to achieve this. I want the model explorer and the generated XML to be wrapped in 'vehicle' but for all other intents and purposes the user is working with a car only
Info: Visual Studio 2010, C# and DSL SDK for 2010
I would try two different approaches:
1st: override DSL Package class DocData
In DocData.cs file and override method
protected override void OnDocumentSaved(System.EventArgs e)
and then I would create the wrapper
afterwards I'd override in DocData.cs
protected override void OnDocumentLoading(System.EventArgs e)
and before calling the base method base.OnDocumentLoading(e); i would delete from the file.
2nd: Under DSL Explorer go to XML Serialization Behaviour and set Car Domain Class "Is Custom = true".
This solution is not straightforward but it's not as complicated as it seems at the first place. You'll must define every single method but for each custom method you can call a DSL generated method called "DefaulMethod" which has the default DSL serializer behaviour.
I am currently using VS 2005, so some things might have changed...
I have fixed this by the following. I am double deriving the Car class and in the Car serializer I am doing this:
Writing the extra elements:
public partial class CarSerializer : CarSerializerBase
{
public override void Write(SerializationContext serializationContext, ModelElement element, XmlWriter writer, RootElementSettings rootElementSettings)
{
// Adds the Model and LobSystem root elements to match that required by the SharePoint BCS
writer.WriteStartElement("Garage");
writer.WriteStartElement("Cars");
base.Write(serializationContext, element, writer, rootElementSettings);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
To be able to read this back in I am overriding the Car LoadModel method in the SerializationHelper and where it is getting the reader I am reading the elements until I get to Car.
....
XmlReader reader = XmlReader.Create(fileStream, settings);
reader.MoveToContent();
while (!reader.EOF && !reader.Name.Equals("Car"))
{
reader.Read();
}
reader = reader.ReadSubtree();
// using (global::System.Xml.XmlReader reader = global::System.Xml.XmlReader.Create(fileStream, settings))
using (reader)
{
....

Resources