To add an ExpressionPropertyAdapter adapter to my vision window's FPMIWindow.InteractionController I need to run setExpression() on the adapter.
Is there a quick way to parse my expression string to the object structure expected by ExpressionPropertyAdapter.setExpression?
private void bindExpression(InteractionController ic, JComponent target, String propName, String expression, Class<?> valueClass) {
// EXAMPLE
// String expression = "getBit({Root Container.test_template_3.tag2},10) &&\ngetBit({Root Container.test_template_3.tag3},10)"
ExpressionPropertyAdapter a = new ExpressionPropertyAdapter();
// build expression
com.inductiveautomation.ignition.common.expressions.Expression e = null; // <--- How to initialize this from String expression ?
a.setExpression(e);
a.setExpressionSource(expression);
a.setTarget(target);
a.setTargetPropertyDynamic(true);
a.setTargetPropertyName(propName);
a.setValueClass(valueClass);
ic.setPropertyAdapter(target, propName, a);
}
Note that the work is in preparing an ExpressionParseContext for your target component's environment.
Thanks,
ELParserHarness requires an ExpressionParseContext, which is where I get stuck.
Trying to figure out how to use ExpressionParseContext right now. Tips?
EDIT: @pturmel yessir. Wondering if there's a builtin ExpressionParseContext?
I know of this one by @paul-griffith :
Pretty sure you need this one, but I'm not sure how to set it up properly.

I suspect some of the key bits you need for Vision aren't in the javadocs.
I found that one too! 
Looks promising. Trying to get intellj to resolve the classpath right now...
Edit: Not sure if it's available at the designer scope. classpath goes [...]igntion.gateway.[...]
ELParserHarness parser = new ELParserHarness();
FunctionFactory functionFactory = new ComponentFunctionFactory(context);
ExpressionParseContext binder =
BindUtilities.newBinder(window, context.getTagManager(), null, functionFactory);
EDIT: Though I'll mention, it looks like potential problems abound:
ExpressionPropertyAdapter newAdapter = new ExpressionPropertyAdapter();
// Go through the expression tree and connect all of the BoundVariableExpressions
try {
BindUtilities.connectBindings(window, context.getTagManager(), expr, newAdapter, newAdapter);
} catch (RuntimeException e) {
if (e.getMessage().isEmpty()) {
ErrorUtil.showError("Unknown error occurred during bound variable connection.", e);
} else {
ErrorUtil.showError(e.getMessage(), e);
}
return false;
}
Component component = context.getComponent();
context.getController().removePropertyAdapter(component, propName);
newAdapter.setExpression(expr);
newAdapter.setExpressionSource(binding.expression);
newAdapter.setOverlayOptOut(binding.overlayOptOut);
Winner, winner, chicken dinner!
Massive, unbelievable dubs today, guys. Thank you so much for your help @bmusson @pturmel @paul-griffith !
private void bindExpression(BindingRoot win, JComponent target, String propName, String expression, Class<?> valueClass) {
// EXAMPLE
// String expression = "getBit({Root Container.test_template_3.tag2},10) &&\ngetBit({Root Container.test_template_3.tag3},10)"
ExpressionPropertyAdapter a = new ExpressionPropertyAdapter();
// build expression
ELParserHarness p = new ELParserHarness();
FunctionFactory ff = context.getExpressionFunctionFactory();
ExpressionParseContext ctx = BindUtilities.newBinder(win, context.getTagManager(), null, ff);
Expression e = null;
try {
e = p.parse(expression, ctx);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
// Go through the expression tree and connect the BoundVariableExpressions
try {
BindUtilities.connectBindings(win, context.getTagManager(), e, a, a);
} catch (RuntimeException ex) {
if (ex.getMessage().isEmpty()) {
ErrorUtil.showError("Unknown error occurred during bound variable connection.", ex);
} else {
ErrorUtil.showError(ex.getMessage(), ex);
}
}
a.setExpression(e);
a.setExpressionSource(expression);
a.setTarget(target);
a.setTargetPropertyDynamic(true);
a.setTargetPropertyName(propName);
a.setValueClass(valueClass);
win.getInteractionController().setPropertyAdapter(target, propName, a);
}