MapBox - Define PropertyFactory.iconImage using expressions - java

I am trying to define the value for the method PropertyFactory.iconImage for my layer object. The return value PropertyValue<String> should use a certain field inside the Feature to define it's value.
The result could look something like that:
PropertyFactory.iconImage(Expression.step(Expression.get("myfield"),"mydefaultValue", Expression.Stop.stop("case1", "valueForCase1"), Expression.Stop.stop("case2", "valueForCase2"));
Unfortunately I was not able to find a similar solution so far.

The following expression solved my problem:
SymbolLayer("asset-layer", "assetMapDataSource").withProperties(
PropertyFactory.iconImage(Expression.match(
Expression.get("asset_type"), Expression.literal("bbq_default"),
Expression.stop("bridge", Expression.literal("bridge_default")))))
Edit:
Some more information why I used the method in my example:
PropertyFactory.iconImage expects a string which points to a certain bitmap that you have saved before via MapBoxMap.addImage(...).
Expression.match is used to "match" a certain String based on the given stop and default cases.
Expression.get is used to access a certain field inside your feature property. In this case the field "asset_type" provides a certain type that I can match against.
The default case of the Expression.match and each Expression.stop are using the Expression.literal. This method is used to tell the underlying expression system that your value is from type x (in that case String). Take a look at the Expression.literal methods to get an idea of that.
Each Expression.stop is used to symbolize that the Expression.match is trying to "match" the given value from the first parameter of Expression.stop against the given Expression.get value. If Expression.get and that method value are the same, the 2nd value of the Expression.stop is used which provides the actual value for the Expression.iconImage. If the underlying expression system wasn't able to find a "matching" stop for the given Expression.get value, the system will use the default value (in that case Expression.literal("bbq_default")).

Related

How to get the value of the arguments of the sonar tree

I'm writing a custom rule for SonarQube for java, I want to check if the value of an argument is qualified. For example, I want to know if the String fit the specific pattern. I can only test if the argument is a String, but I can not get the exact value. Does the API allows me to do so?
For example, for the code below
log.error("errorID:210134 It's an error");
Can I get the argument and test if the string contains errorID?
Besides, can I get what variable did the method invocation?
For example, for the code below
log.error("errorID:210134 It's an error");
How can I know that log is an Object of the class Logger?
The following should do the trick:
When looking at the argument of the method invocation, check if its kind is a STRING_LITERAL, then cast the argument into a LiteralTree. From there, you will be able to access its value, as a String (Note that it will contain the double quotation marks).
To check if the invocation was done on a variable, get the methodSelect() expression tree from the method invocation. If its kind is a MEMBER_SELECT, cast it to MemberSelectExpressionTree. From there, check if the kind of the expression() is an IDENTIFIER. If it's the case, then you will be able to get the IdentifierTree and its associated symbol. You will then be able to say if the symbol calling the method is a variable or not, check its type, etc.

How to pass Java null strings to Fitnesse

Following the Fitnesse TestBlankAndNullCells documentation, I am trying to pass null fields into the verify tables. My data types are Strings.
When I leave the field blank, there is a solid red square with no information. When I try adding "null," the actual is empty. The same problem occurred using "blank". Am I missing something?
Here is more documentation on it, which states the keywords "blank" or "null" are required. I was able to manually return the string "null" as the actual, which works when the expected is also the literal "null," but I am hoping to find a cleaner solution in which I can pass in null fields.
According to this question on the Fitnesse forums, it looks like Strings are treated differently with null values.
In the Java world, there are some differences in the way nulls are handled between the 'classic' fixtures like ColumnFixture and the FitLibrary fixtures developed by Rick. My guess is the classic fixtures support the 'null' keyword but FitLibrary doesn't.
In the .NET world, the 'null' keyword is supported by all fixtures.
I found a solution after browsing the Fitnesse forums, straight from one of the developers for Fit, Rick Mugridge:
public String findString(String s) {
if ("".equals(s))
return null;
return s;
}
}
I included this in the ArrayFixture and it worked! Here are some interesting points from Rick's message:
When the myList() method is called for the second table, FitLibrary
automatically wraps it with a SetFixture (because the returned value is
a Set). When it checks each of the name elements, which are of type
String, it determines that there is a findString() method of the right
types, so it calls it to parse the value from the cells in the name
column. That method turns an empty string into a null so that it will
match correctly with the actual value of null.
For any type T, FitLibrary checks for a method public Object
findT(String s). It calls it to parse the String value from a table
cell. This can be used in several ways.
SetFixture, ArrayFixture,
etc will access private instance variables if necessary (eg, no
getter)
Arrays, Lists, Maps, Sets and other Objects are all
auto-wrapped with an appropriate fixture in flow
Flow occurs when
the first fixture in a DoFixture (In the next release, a DoFixture
doesn't need to be the first fixture for flow to occur; it just
starts later.)

How to change value for parameters using reformat component in Clover ETL

I am trying to find out a method on how to change the value of a parameter that I have defined and also how to create a new parameter dynamically using REFORMAT component in Clover ETL.
I have written small logic in my transform method which reformat component provides:
function integer transform() {
string myparam1 = getParamValue("MY_PARAM1");
string changeParam = getParamValue("CHANGE_PARAM_VALUE");
if(changeParam =="true"){
myparam1 = myparam1 +"_changed";
}
// update the value of parameter MY_PARAM1
// updateParameter("MY_PARAM1", myparam1 );
// create a new parameter
// createNewParameter("MY_NEW_PARAM", "some_sample_data");
return OK;
}
From clover designer I tried to check for available methods but I have not found any relevant method that helps me to provide the feature that I am looking for.
I am new to Clover ETL so I am facing difficulty in how to accomplish this, please help me if we can achive this using REFORMAT component or do we need to use a different component?
You cannot change value(in easy way, there is maybe a way through direct access with java and model of graph, but this is probably not what you need) of parameters in CloveETL as they are used in static way, all occurences of parameters are resolved during compilation of graph and replaced with resulted values.
If you need dynamic variables, take a look at dictionaries http://doc.cloveretl.com/documentation/UserGuide/topic/com.cloveretl.gui.docs/docs/using-dictionary.html?resultof=%22%64%69%63%74%69%6f%6e%61%72%79%22%20
But you need to think, that dictionary aren't dead replacement for parameters. Static usage of parameters has some points, places of usage, that you cannot replace with dictionary.
BTW why you need to change parameter value during run of the graph? Please explain use case and maybe I could give you some pointers...
You cannot change value of graph parameters as they are set during the initialization phase of the graph.
However, there are a couple of ways of achieving what you probably want:
Opt 1: Run your graph on a schedule and then passing the parameter value from the scheduler.
Opt 2: Whatever component(s) need the modified value of the parameters put them in a subgraph and create a sub-graph parameter with the same name and pass the modified value as part of your input mapping from the main graph to the sub-graph.

Access variable/constant values in method call

I want to view arguments for method calls. So if I call foo:
x = 4;
y = 5;
...
foo(x, y, 20, 25);
I want to print the arguments(4,5,20,25)
I understand these arguments are pushed onto the stack before the method is invoked. How do I get the value(if initialized or a constant) from the method's local variable array?
visitVarInsn() and VarInsnNode do not have a way to lookup the actual value from the array.
Do I need to use an Analyzer and Interpreter to do this, or is there an easier way?
EDIT: Figured out how to do this.
I modified BasicValue and BasicInterpreter to account for bytecode instruction arguments.
So Values representing instructions like BIPUSH contain information about the value being pushed, instead of only type information.
Frames are examined the same way with an Analyzer
Constant numeric values passed directly to the method call (20 and 25) are easy to retrieve statically - they will result in push instructions that you can read in visitIntInsn. Smaller values will result in const instructions you can catch with visitInsn, large values can be caught with visitLdcInsn.
I don't believe it is generally possible to determine the values bound to variables at the point of the method call statically. You will need to do a dataflow analysis (using Analyzer and Interpreter as you suggest) which should be able to provide the range of possible values for each variable. This won't give you definite values in the general case, but will in the specific cases of variables that are only assigned once or assigned multiple times, but unconditionally.
it's not related to asm and bytecode manipulation, but just in case -
if method foo belongs to a class with interface method foo you may use Proxy to wrap interface implementation and intercept method names.
Also, you may found this answer useful for ASM bytecode modifications.

How to inspect the stack using an ASM visitor?

I am attempting to use the Java byte code engineering library ASM to perform static analysis. I have the situation where I would like to inspect the variables being assigned to a field.
I have MethodVisitor which implements the visitFieldInsn() method. I am specifically looking for the putfield command. That is no problem. The problem is that when I encounter putfield, I want to be able to access the variable that's going to be assigned to the field. Specifically I want to access information about the type of the variable.
At the moment I really only need to look at what's at the top of the stack, but if there's a more general way to inspect it that's even better.
Is there a way using ASM to inspect the variables on the stack?
First of all, if you can assume that bytecode is valid, the type of value assigned to a field should match the field type, which you can read in advance using ClassReader API.
However if you need to track where each individual value on a stack or variable slot for given instruction pointer came from, you can use the Analyzer API with SourceInterpreter. Basically it would allow to find instruction that produced given value and you can use information about that instruction to deduce a type (e.g. if it reads from a variable which corresponds to a method parameter or if value been returned from a method call, so in both cases you can get the type from method descriptor). Also see my old blog post that has an example of using SourceInterpreter.
I am not familiar with ASM, but I have done something that sounds similar with the Eclipse Java AST framework. To know about variables, I had to keep track of variable declarations myself in the appropriate visitX() methods of the AST visitor. It wasn't very difficult once I knew which AST nodes corresponded to variable declarations.

Categories

Resources