Inheriting interface in Vala - incompatible with base method - c

I'm trying to implement a Gtk.StyleProvider in Vala. The "base class" (in C) looks like:
GtkIconFactory * gtk_style_provider_get_icon_factory ()
GtkStyleProperties * gtk_style_provider_get_style ()
gboolean gtk_style_provider_get_style_property ()
and in VAPI:
[CCode (cheader_filename = "gtk/gtk.h")]
public interface StyleProvider {
public abstract unowned Gtk.IconFactory get_icon_factory (Gtk.WidgetPath path);
public abstract unowned Gtk.StyleProperties get_style (Gtk.WidgetPath path);
public abstract bool get_style_property (Gtk.WidgetPath path, Gtk.StateFlags state, GLib.ParamSpec pspec, GLib.Value value);
}
Where the first two methods should only return NULL according to the documentation for GtkStyleProvider.
Thus, I wrote some Vala like this:
public class DerivedStyleProvider : Gtk.StyleProvider
{
public Gtk.IconFactory? get_icon_factory (Gtk.WidgetPath path)
{
return null;
}
public Gtk.StyleProperties? get_style (Gtk.WidgetPath path)
{
return null;
}
bool get_style_property (Gtk.WidgetPath path,
Gtk.StateFlags state,
GLib.ParamSpec pspec,
out GLib.Value value)
{
return false; //TODO
}
}
I have a problem with the first two methods. If I have them as written here (with a ?), then I get the following error:
error: overriding method `DerivedStyleProvider.get_icon_factory' is incompatible
with base method `Gtk.StyleProvider.get_icon_factory': Base method expected
return type `Gtk.IconFactory', but `Gtk.IconFactory?' was provided.
public Gtk.IconFactory? get_icon_factory (Gtk.WidgetPath path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The gtk_style_provider_get_style() method is the same.
If I remove the ?, I get the following two errors per method:
error: overriding method `DerivedsStyleProvider.get_icon_factory'
is incompatible with base method `Gtk.StyleProvider.get_icon_factory': Base
method expected return type `Gtk.IconFactory', but `Gtk.IconFactory' was provided.
public Gtk.IconFactory get_icon_factory (Gtk.WidgetPath path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/Preferences.vala:138.3-138.14: warning: `null' incompatible with
return type `Gtk.IconFactory`
return null;
^^^^^^^^^^^
The first error especially is a bit strange to me, as the upshot is "error: expected TYPE, got TYPE"!
Adding unowned to the first two methods still results in similar errors.
How should I implement a Gtk.StyleProvider interface in Vala?

This compiles without errors or warnings on my system (Vala 0.32.1):
public class DerivedStyleProvider : GLib.Object, Gtk.StyleProvider
{
public unowned Gtk.IconFactory get_icon_factory (Gtk.WidgetPath path)
{
// Evil cast to work around buggy declaration in VAPI file
return (Gtk.IconFactory) null;
}
public Gtk.StyleProperties get_style (Gtk.WidgetPath path)
{
// Evil cast to work around buggy declaration in VAPI file
return (Gtk.StyleProperties) null;
}
bool get_style_property (Gtk.WidgetPath path,
Gtk.StateFlags state,
GLib.ParamSpec pspec,
out GLib.Value value)
{
// I just assigned something here to make the compiler happy, you should make sure to use a correct value
value = Value (typeof (string));
return false; //TODO
}
}
I made these changes:
Derive from GLib.Object in addition to the interface.
Use unowned on the first method.
Remove the nullable from the return types.
Cast null into the actual class types. (Which is not pretty, but the problem is with the vapi file.)
Assign a dummy value to the out parameter to make compiling warning free ;)

Related

Camel set body to object with header expression

Is it possible to set a response body to an object and pass in a camel header property. I can achieve this in a processor but I'd rather do it in line of the route.
.setBody(constant(
new Foo()
.withOne("HelloWorld")
.withTwo(simple("Header property is ${header.uniqueProperty}").toString())
))
With the above code I get a response of:
<foo>
<one>HelloWorld</one>
<two>Header property is ${header.uniqueProperty}</two>
</foo>
Here is my POJO
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
private String one;
private String two;
public String getOne() {
return one;
}
public void setOne(final String one) {
this.one = one;
}
public String getTwo() {
return two;
}
public void setTwo(final String two) {
this.two = two;
}
public Foo withOne(final String one) {
setOne(one);
return this;
}
public Foo withTwo(final String two) {
setTwo(two);
return this;
}
}
constant() probably won't work for you, since you probably want this dynamically evaluated for every exchange that passes through. Since you need to set the body to a newly instantiated object, you need a mechanism that's capable of this. You mentioned you want to avoid a processor, but I'd like to point out how simple this could be done in the route:
.setBody(exchange -> new Foo()
.withOne("HelloWorld")
.withTwo(simple("Header property is " + exchange.getIn().getHeader("uniqueProperty")))
)
Edit: Actually this is not a processor. We're just passing a lambda (Function) to setBody().
If you're in a Spring environment, you could use spring expression language:
.setBody().spel("#{new Foo()" +
".withOne('HelloWorld')" +
".withTwo(simple('Header property is ' + request.headers.uniqueProperty))}");

Trouble reading from Storage

Ive had a deeper look at the storage system now, but I just can't get it to work properly. The data seems to be saved, the saved data is definitely not empty and I am still getting a java.lang.NullPointerException.
So here is my Class i want to saved and later read to the Storage.
Band is a trivial Class with name and genre String.
public class Band implements Externalizable{
String name;
String genre;
public Band(String bnd, String gen){
this.name = bnd;
this.genre = gen;
}
public Band() {
}
public String getName(){
return this.name;
}
public String getGenre() { return this.genre; }
public void setName(String name) {
this.name = name;
}
public void setGenre(String genre) {
this.genre = genre;
}
#Override
public String toString(){
String s;
s = this.name;
return s;
}
public int getVersion(){
return 1;
}
#Override
public void externalize(DataOutputStream out) throws IOException {
Util.writeUTF(name, out);
Util.writeUTF(genre, out);
}
#Override
public void internalize(int version, DataInputStream in) throws IOException {
name = Util.readUTF(in);
genre = Util.readUTF(in);
}
public String getObjectId(){
return "Band";
}
}
BandList is just a Class with an ArrayList the Bands are added to.
public class BandList implements Externalizable{
List <Band> bandList;
public List getBandList(){
return this.bandList;
}
public BandList(){
bandList = new ArrayList<Band>();
}
public void setBandList(List<Band> bandList) {
this.bandList = bandList;
}
public int getVersion(){
return 1;
}
#Override
public void externalize(DataOutputStream out) throws IOException {
Util.writeObject(bandList, out);
}
#Override
public void internalize(int version, DataInputStream in) throws IOException {
bandList = (ArrayList<Band>) Util.readObject(in);
}
public String getObjectId(){
return "BandList";
}
}
So, in some other class where the user filled in some TextFields, the band gets added to the BandList and therefore I call saveListsToStorage();
public void saveListsToStorage(){
Storage.getInstance().clearStorage();
Storage.getInstance().writeObject("Bands", bandList);
}
So now, when starting the App, the App is looking for Data in the Storage, if found, it will return the BandList Object stored, otherwise it will return a new BandList Object.
Before that, I regist the Classes with
Util.register("Band", Band.class);
Util.register("BandList", BandList.class);
and finally call this method in the main at the beginning:
public BandList loadSavedBandList() {
String[] temp = Storage.getInstance().listEntries();
for (String s : temp) {
if (s.equals("Bands") == true) {
BandList tempBand = (BandList) Storage.getInstance().readObject("Bands");
return tempBand;
}
}
return new BandList();
}
After saving and then loading it throws the NullPointer exception and I have no clue why. I now used ArrayList instead of LinkedList as Shai told me and I implemented the Externalizable Interface as told in the guide.
Maybe some of you can tell me whats wrong here.
Edit:
Here is the Exception:
java.lang.NullPointerException
at com.rosscode.gehma.Menu_Form.updateBandContainer(Menu_Form.java:95)
at com.rosscode.gehma.Menu_Form.<init>(Menu_Form.java:73)
at com.rosscode.gehma.main.start(main.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.codename1.impl.javase.Executor$1$1.run(Executor.java:106)
at com.codename1.ui.Display.processSerialCalls(Display.java:1152)
at com.codename1.ui.Display.mainEDTLoop(Display.java:969)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
Edit 2, Line 95:
if(bandList.getBandList().isEmpty() == false) {
for (int i = 0; i < bandList.getBandList().size(); i++) {
Button temp = new Button(bandList.getBandList().get(i).toString());
temp.addActionListener((e) ->
nextStep()
);
listCont.add(temp);
}
menuForm.revalidate();
}
NullPointerExceptions are pretty amazing things, because not only are they easy to figure out, they even show you the exact line where they happen. All you have to do is look at anything left of a . and check if it's null. As soon as you find it, you find the problem.
So let's look at your code. Sadly I don't know which of those lines is line 95 but I'm guessing it's the one starting with if.
That means either bandList is null or bandList.getBandList() returns null. A quick look into getBandList() shows that it won't be null, as you initialize the list in the constructor of your BandList class. Which only leaves bandList.
Sadly you didn't post where you got that from, but I'm gonna assume you just did something like:
BandList bandList = loadSavedBandList();
So let's look into that method. (btw: I say a bit more about where you have to look if you didn't do this at the end of this answer).
If you couldn't find your key, it would return a new BandList, which couldn't be null. So it has to find something, meaning the key exist but the value is null.
So let's take another step and look at how you save things in the first place.
public void saveListsToStorage(){
Storage.getInstance().clearStorage();
Storage.getInstance().writeObject("Bands", bandList);
}
Now "in some other class" doesn't really explain much. But since you read a null, it means you are writing a null here. Which would mean in this "other class", at least in this method, bandList = null.
With the code you gave, it's impossible for me to look deeper into this issue, but it seems like in "that other class", you got a class attribute named bandList but fail to put anything inside it.
Or maybe you saved everything right, but didn't call
BandList bandList = loadSavedBandList();
in some form or another before your if, which would also pretty much explain the problem. I mean... if you never load the bandList, it will obviously be null...

Is it possible to pass Java-Enum as argument from cucumber feature file

I am currently using selenium with Java,And want to implement cucumber to make test script more readable.
Currently facing issue while passing argument to java method where Enum is expected as parameter.
I would also like to know if there are any other known limitations of cucumber-java before migrating current framework.
The answer is: Yes
You can use all kind of different types in your scenario: primitive types, own classes (POJOs), enums, ...
Scenario :
Feature: Setup Enum and Print value
In order to manage my Enum
As a System Admin
I want to get the Enum
Scenario: Verify Enum Print
When I supply enum value "GET"
Step definition code :
import cucumber.api.java.en.When;
public class EnumTest {
#When("^I supply enum value \"([^\"]*)\"$")
public void i_supply_enum_value(TestEnum arg1) throws Throwable {
testMyEnum(arg1);
}
public enum TestEnum {
GET,
POST,
PATCH
}
protected void testMyEnum(TestEnum testEnumValue) {
switch (testEnumValue) {
case GET:
System.out.println("Enum Value GET");
break;
case POST:
System.out.println("Enum Value POST");
break;
default:
System.out.println("Enum Value PATCH");
break;
}
}
}
Let me know how you are doing. I could try to help you.
This youtube lecture of about 11 minutes gives a good way of doing it.
https://www.youtube.com/watch?v=_N_ca6lStrU
For example,
// enum, obviously in a separate file,
public enum MessageBarButtonType {
Speak, Clear, Delete, Share
}
// method for parameter type. if you want to use a different method name, you could do #ParameterType(name="newMethodName", value="Speak|Clear|Delete|Share") according to the video.
#ParameterType("Speak|Clear|Delete|Share")
public MessageBarButtonType MessageBarButtonType(String buttonType) {
return MessageBarButtonType.valueOf(buttonType);
}
// use like this. the name inside {} should match the name of method, though I just used the type name.
#Then("Select message bar {MessageBarButtonType} button")
public void select_message_bar_button(MessageBarButtonType buttonType) {
...
}
First register a transformer based on an ObjectMapper, then you can just use enums as would be expected.
private final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
#DefaultParameterTransformer
#DefaultDataTableEntryTransformer
#DefaultDataTableCellTransformer
public Object defaultTransformer(Object fromValue, Type toValueType) {
JavaType javaType = objectMapper.constructType(toValueType);
return objectMapper.convertValue(fromValue, javaType);
}
Scenario: No.6 Parameter scenario enum
Given the professor level is ASSOCIATE
#Given("the professor level is {}")
public void theProfessorLevelIs(ProfLevels level) {
System.out.println(level);
System.out.println("");
}
public enum ProfLevels {
ASSISTANT, ASSOCIATE, PROFESSOR
}
Source
This is no more supported in latest io.cucumber maven group
https://github.com/cucumber/cucumber-jvm/issues/1393

ITypeConverter interface has been changed in AutoMapper 2.0

The ITypeConverter interface has been changed to have a "TDestination Convert(ResolutionContext context)" instead of "TDestination Convert(TSource source)" for the Convert method.
http://automapper.codeplex.com/wikipage?title=Custom%20Type%20Converters
In my code, now I get this error:
'BusinessFacade.Mappers.DecimalToNullableInt' does not implement
interface member
'AutoMapper.ITypeConverter.Convert(AutoMapper.ResolutionContext)'
Any good full sample for new mapper like my mappers ? I don't want change any code (or minimum code) in my projects...
My mapper
public class DecimalToNullableInt : ITypeConverter<decimal, int?>
{
public int? Convert(decimal source)
{
if (source == 0)
return null;
return (int)source;
}
}
UPDATE
The ITypeConverter interface has been changed to have a "TDestination Convert(ResolutionContext context)" instead of "TDestination Convert(TSource source)" for the Convert method.
the documentation is just out of date. There is an ITypeConverter, as
well as a base TypeConverter convenience class. The TypeConverter hides the
ResolutionContext, while ITypeConverter exposes it.
http://automapper.codeplex.com/wikipage?title=Custom%20Type%20Converters
https://github.com/AutoMapper/AutoMapper/wiki/Custom-type-converters
http://groups.google.com/group/automapper-users/browse_thread/thread/6c523b95932f4747
You'll have to grab the decimal from the ResolutionContext.SourceValue property:
public int? Convert(ResolutionContext context)
{
var d = (decimal)context.SourceValue;
if (d == 0)
{
return null;
}
return (int) d;
}

Silverlight 4 - Type.GetType() not working across assemblies

Basically the problem is that I'd like to invoke a method in an unreferenced assembly, but can't seem to find the right call for instantiating the class. I've tried things like a simple Type t = Type.GetType("MyApp.Helper") which returns null, and Assembly.LoadFrom("MyApp.Helper") which throws a security exception.
In the example below, two projects/assemblies (Helper.dll and Menu.dll) are compiled separately into a common 'libs' folder, but do not reference each other. Main.dll references both, and the references are set to 'Copy local' in VS. So when the app runs, the Main.xap should contain all three assemblies and they should be loaded into the same application domain. Or so goes my understanding. Is this an impossible quest? I see lots of comments regarding plug-ins but so far I haven't seen examples for this specific design. For example, I suppose I could do something like Jeff Prosise describes here, but I'd rather have everything in one package.
Here's a sketch of my code:
In one project/assembly, I have a worker class:
namespace MyApp.Helper {
public class Helper {
public void ShowHelp() {
Console.Write("Help!");
}
}
}
In another project/assembly, I have a menu class which tries to invoke the helper:
namespace MyApp.Menu {
public class Selector {
public void InvokeSelection(string className, string functionName) {
// fails: t will be null
Type t = Type.GetType(className);
// fails: t will be null
t = Type.GetType(string.Format("{0}.{1}, {0}, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null", "MyApp.Helper", "Helper"));
// however, this works (reference to main assembly?)
t = Type.GetType(string.Format("{0}.{1}, {0}, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null", "MyApp.Main", "Worker"));
// and, I'd like to do something like the following
// t.InvokeMember(functionName, ...);
}
}
}
Finally, I have the main app assembly:
namespace MyApp.Main {
public class Main {
public static void Main() {
MyApp.Menu.Selector sel = new Menu.Selector();
sel.InvokeSelection("MyApp.Help.Helper", "ShowHelp"); // fails
sel.InvokeSelection("MyApp.Main.Main", "Worker"); // works in some cases
}
public void Worker() {
Console.Write("Work!");
}
}
}
Thanks for any ideas!
-Chris.
You need to get the Assembly object, then call its GetType method.
However, I don't see why you're using Reflection at all.
You can call the method normally from your main project.
First, you should note that since it's SL, you can't invoke private/protected/internal members.
Second, try this:
public void InvokeSelection(string className, string functionName) {
var asm = Assembly.Load("MyApp.Helper, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null"); // double check this is correct!
Type t = asm .GetType(className);
// and, I'd like to do something like the following
// t.InvokeMember(functionName, ...);
}

Resources