I want to access Hashmap from another class for Rule writing how can i do that?
Class Nov{
public static main()
...
public static HashMap<Object, Object> parseJson(JSONObject jsonObject) throws ParseException {
Set<Object> set = jsonObject.keySet();
Iterator<Object> iterator = set.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
if (jsonObject.get(obj) instanceof JSONArray)
{
getArray(jsonObject.get(obj));
}
else {
}
}
Related
I'm trying to write java beans that can be loaded from a Groovy config file. The config format expects properties in closures and if I don't call c.setResolveStrategy(Closure.DELEGATE_FIRST) then all properties set inside the closures end up as binding variables. My program outputs:
In closure
confpojo.myTestProp: null
binding.myTestProp: true
confpojo.app.myOther.myTestSubProp: null
binding.myTestSubProp: true
In this answer https://stackoverflow.com/a/10761284/447503 they don't change the default resolveStrategy and it seems to work. What's the difference? configaaa.groovy:
app {
println 'In closure'
myTestProp = true
myOther {
myTestSubProp = true
}
}
_
public abstract class AaaTestGroovyConfig extends Script {
public static class App {
public void myOther(final Closure c) {
c.setDelegate(myOther);
// c.setResolveStrategy(Closure.DELEGATE_FIRST);
c.call();
}
private Boolean myTestProp;
private final Other myOther = new Other();
public Boolean getMyTestProp() {
return myTestProp;
}
public void setMyTestProp(final Boolean active) {
this.myTestProp = active;
}
}
public void app(final Closure c) {
c.setDelegate(app);
// c.setResolveStrategy(Closure.DELEGATE_FIRST);
c.call();
}
private App app = new App();
public static void main(final String[] args) throws Exception {
final CompilerConfiguration cc = new CompilerConfiguration();
cc.setScriptBaseClass(AaaTestGroovyConfig.class.getName());
// final ClassLoader cl = AaaTestGroovyConfig.class.getClassLoader();
final Binding binding = new Binding();
final GroovyShell shell = new GroovyShell(binding, cc);
final Script script = shell.parse(new File("configaaa.groovy"));
final AaaTestGroovyConfig confpojo = (AaaTestGroovyConfig) script;
// ((DelegatingScript) script).setDelegate(confpojo);
script.run();
System.out.println("confpojo.myTestProp: " + confpojo.app.myTestProp);
printBindingVar(binding, "myTestProp");
System.out
.println("confpojo.app.myOther.myTestSubProp: " + confpojo.app.myOther.myTestSubProp);
printBindingVar(binding, "myTestSubProp");
}
private static void printBindingVar(final Binding binding, final String name) {
System.out
.println(
"binding." + name + ": " + (binding.hasVariable(name)
? binding.getVariable(name)
: ""));
}
public static class Other {
private Boolean myTestSubProp;
public Boolean getMyTestSubProp() {
return myTestSubProp;
}
public void setMyTestSubProp(final Boolean myTestSubProp) {
this.myTestSubProp = myTestSubProp;
}
}
public App getApp() {
return app;
}
public void setApp(final App app) {
this.app = app;
}
}
because the default value is OWNER_FIRST
https://docs.groovy-lang.org/latest/html/api/groovy/lang/Closure.html#OWNER_FIRST
and you have 2 levels of closures so - owners are different for them
try something like this and you'll see the difference
app {
println "delegate=$delegate owner=${owner.getClass()}"
myOther {
println "delegate=$delegate owner=${owner.getClass()}"
}
}
PS: let me suggest you to make your code groovier:
//generic config class
class MyConf {
private HashMap objMap
static def build(HashMap<String,Class> classMap, Closure builder){
MyConf cfg = new MyConf()
cfg.objMap = classMap.collectEntries{ k,cl-> [k, cl.newInstance()] }
cfg.objMap.each{ k,obj->
//define method with name `k` and with optional closure parameter
cfg.metaClass[k] = {Closure c=null ->
if(c) {
// call init closure with preset delegate and owner
return c.rehydrate(/*delegate*/ obj, /*owner*/cfg, /*this*/cfg).call()
}
return obj //return object itself if no closure
}
}
cfg.with(builder) // call root builder closure with cfg as a delegate
return cfg
}
}
//bean 1
#groovy.transform.ToString
class A{
int id
String name
}
//bean 2
#groovy.transform.ToString
class B{
int id
String txt
}
//beans init
def cfg = MyConf.build(app:A.class, other:B.class){
app {
id = 123
name = "hello 123"
other {
id = 456
txt = "bye 456"
}
}
}
//get initialized beans
println cfg.app()
println cfg.other()
It surprise me!
According to the document of groovy, groovy may use "getProperty" method to get the property of a object. So when I want to change the behavier of getting property on the special object, I use a category class to override the "getProperty" method. However, it does not work.
At last, I found groovy framework use the "get" method in the category class to get property, even if the object is not a map.
My question is that is it a bug or groovy just work like that.
This is the category class.
class DynaBeanExtension {
public static void setProperty(DynaBean bean, String propertyName, def newValue) {
try {
PropertyUtilsBean pu = null;
if (bean instanceof CustomWrapDynaBean) {
pu = bean.propertyUtilsBean;
}
if (pu != null) {
pu.setProperty(bean, propertyName, newValue);
} else {
PropertyUtils.setProperty(bean, propertyName, newValue);
}
} catch (IllegalArgumentException ex) {
bean.propertyMissing(propertyName, newValue);
}
}
public static def getProperty(DynaBean bean, String propertyName) {
try {
PropertyUtilsBean pu = null;
if (bean instanceof CustomWrapDynaBean) {
pu = bean.propertyUtilsBean;
}
if (pu != null) {
return pu.getProperty(bean, propertyName);
} else {
return PropertyUtils.getProperty(bean, propertyName);
}
} catch (IllegalArgumentException ex) {
return bean.propertyMissing(propertyName);
}
}
public static def get(DynaBean bean, String propertyName) {
try {
PropertyUtilsBean pu = null;
if (bean instanceof CustomWrapDynaBean) {
pu = bean.propertyUtilsBean;
}
if (pu != null) {
return pu.getProperty(bean, propertyName);
} else {
return PropertyUtils.getProperty(bean, propertyName);
}
} catch (IllegalArgumentException ex) {
return bean.propertyMissing(propertyName);
}
}
This is the test code:
public static class TestSubClass {
private final int e = 3, f = 4;
private final Map<String, Object> m = new HashMap<>();
public int getE() {
return e;
}
public int getF() {
return f;
}
public Map<String, Object> getM() {
return m;
}
#Override
public String toString() {
return "TestSubClass{" + "e=" + e + ", f=" + f + ", m=" + m + '}';
}
}
public static class TestClass {
private final int a = 1;
private final TestSubClass b = new TestSubClass();
public int getA() {
return a;
}
public TestSubClass getB() {
return b;
}
#Override
public String toString() {
return "TestClass{" + "a=" + a + ", b=" + b + '}';
}
}
Map<String, String> pMap = new HashMap<>();
pMap.put("b.e", "c");
PropertyUtilsBean pu = new PropertyUtilsBean();
pu.setResolver(new ExResolver(pMap));
TestClass testObj = new TestClass();
DynaBean bean = new CustomWrapDynaBean(testObj, pu);
int c = use(DynaBeanExtension) {
bean.c;
}
This is the code of ExResolver:
public class ExResolver implements Resolver {
private static final char NESTED = '.';
private static final char MAPPED_START = '(';
private static final char MAPPED_END = ')';
private static final char INDEXED_START = '[';
private static final char INDEXED_END = ']';
private final Resolver resolver;
private final Map<String, String> pMap;
public ExResolver(Map<String, String> pMap) {
this(new DefaultResolver(), pMap);
}
public ExResolver(Resolver resolver, Map<String, String> pMap) {
this.resolver = resolver;
this.pMap = new HashMap<>(pMap);
}
private String resolveExpr(String expression) {
for (Map.Entry<String, String> entry : pMap.entrySet()) {
if (expression.startsWith(entry.getValue())) {
String to = entry.getValue();
if (expression.length() == entry.getValue().length()) {
return entry.getKey();
} else {
int toTest = expression.codePointAt(to.length());
if (toTest == NESTED || toTest == MAPPED_START || toTest == INDEXED_START) {
return entry.getKey() + expression.substring(to.length(), expression.length());
} else {
return expression;
}
}
}
}
return expression;
}
#Override
public int getIndex(String expression) {
expression = resolveExpr(expression);
return resolver.getIndex(expression);
}
#Override
public String getKey(String expression) {
expression = resolveExpr(expression);
return resolver.getKey(expression);
}
#Override
public String getProperty(String expression) {
expression = resolveExpr(expression);
return resolver.getProperty(expression);
}
#Override
public boolean hasNested(String expression) {
expression = resolveExpr(expression);
return resolver.hasNested(expression);
}
#Override
public boolean isIndexed(String expression) {
expression = resolveExpr(expression);
return resolver.isIndexed(expression);
}
#Override
public boolean isMapped(String expression) {
expression = resolveExpr(expression);
return resolver.isMapped(expression);
}
#Override
public String next(String expression) {
expression = resolveExpr(expression);
return resolver.next(expression);
}
#Override
public String remove(String expression) {
expression = resolveExpr(expression);
return resolver.remove(expression);
}
}
"get" is invoked, not "getProperty"
What's more, in the real situation DynaBeanExtension is compiled with groovy. The construction of bean is compiled with java. Then by using binding, I put it into the test code which is a runtime script executed by java code.
This happens in the compilation itself. Let's look at a simpler example.
class Main {
static void main(def args) {
Foo foo = new Foo()
foo.str = ""
foo.str
}
}
For Groovy classes
class Foo {
String str
}
If you decompile the Main class, you'll see it is
public class Main implements GroovyObject {
public Main() {
Main this;
CallSite[] arrayOfCallSite = $getCallSiteArray();
MetaClass localMetaClass = $getStaticMetaClass();
this.metaClass = localMetaClass;
}
public static void main(String... args) {
CallSite[] arrayOfCallSite = $getCallSiteArray();
Foo foo = (Foo)ScriptBytecodeAdapter.castToType(arrayOfCallSite[0].callConstructor(Foo.class), Foo.class);
String str = "";
ScriptBytecodeAdapter.setGroovyObjectProperty(str, Main.class, foo, (String)"str");
arrayOfCallSite[1].callGroovyObjectGetProperty(foo);
}
}
A .[property] = call gets compiled to a ScriptBytecodeAdapter.setGroovyObjectProperty, that in turn calls the chain MetaClassImpl.setProperty > MetaMethod.doMethodInvoke > CachedMethod.invoke > java.lang.reflect.Method.invoke > [setter]
And a .[property] call gets compiled to a arrayOfCallSite[1].callGroovyObjectGetProperty, that in turn calls the chain
AbstractCallSite.callGroovyObjectGetProperty > GetEffectivePogoPropertySite.getProperty > MethodMetaProperty$GetBeanMethodMetaProperty.getProperty > MetaMethod.doMethodInvoke > CachedMethod.invoke > java.lang.reflect.Method.invoke > [getter]
For Java classes
If you use a Java version of the class being called, like this
public class Foo {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
The same Main decompiles to
public class Main implements GroovyObject {
public Main() {
Main this;
CallSite[] arrayOfCallSite = $getCallSiteArray();
MetaClass localMetaClass = $getStaticMetaClass();
this.metaClass = localMetaClass;
}
public static void main(String... args) {
CallSite[] arrayOfCallSite = $getCallSiteArray();
Foo foo = (Foo)ScriptBytecodeAdapter.castToType(arrayOfCallSite[0].callConstructor(Foo.class), Foo.class);
String str = "";
ScriptBytecodeAdapter.setProperty(str, null, foo, (String)"str");
arrayOfCallSite[1].callGetProperty(foo);
}
}
A .[property] = call gets compiled to a ScriptBytecodeAdapter.setProperty, that in turn calls the chain [Class].setProperty > InvokerHelper.setProperty -> MetaClassImpl.setProperty > MetaMethod.doMethodInvoke > CachedMethod.invoke > java.lang.reflect.Method.invoke > [setter]
And a .[property] call gets compiled to a arrayOfCallSite[1].callGroovyObjectGetProperty, that in turn calls the chain
AbstractCallSite.callGetProperty > GetEffectivePojoPropertySite.getProperty > MethodMetaProperty$GetBeanMethodMetaProperty.getProperty > MetaMethod.doMethodInvoke > CachedMethod.invoke > java.lang.reflect.Method.invoke > [getter]
To correct your code
As you can see from these dispatch chains, you've overridden the getter correctly (since it happens in the class itself), but if you want to override getProperty or setProperty, you have to do this in metaClass, and not the class itself. The behavior you're seeing is expected. This code demonstrates how to override each
class Foo {
String bar
}
// override using setter in category
#Category(Foo)
class FooCategory {
public String getBar() {
println "in getter"
}
public void setBar(String bar) {
println "in setter"
}
}
use (FooCategory) {
Foo foo = new Foo()
foo.bar = ""
foo.bar
}
// override using metaClass
Foo.metaClass.getProperty { String pname ->
println "in getProperty"
}
Foo.metaClass.setProperty { String pname, Object pValue ->
println "in setProperty"
}
Foo foo = new Foo()
foo.bar = ""
foo.bar
outputs
in setter
in getter
in setProperty
in getProperty
And because the getProperty/setProperty call makes the dispatch (eventually) to the getter/setter, you can prevent the getter/setter from being called at all, like this
class Foo {
String bar
}
Foo.metaClass.getProperty { String pname ->
println "in getProperty"
}
Foo.metaClass.setProperty { String pname, Object pValue ->
println "in setProperty"
}
#Category(Foo)
class FooCategory {
String getBar() {
println "in getter"
}
void setBar(String bar) {
println "in setter"
}
}
use (FooCategory) {
Foo foo = new Foo()
foo.bar = "hi foo1"
foo.bar
}
outputs
in setProperty
in getProperty
I want to convert a tree in a Java8 stream of nodes.
Here is a tree of nodes storing data which can be selected:
public class SelectTree<D> {
private D data;
private boolean selected = false;
private SelectTree<D> parent;
private final List<SelectTree<D>> children = new ArrayList<>();
public SelectTree(D data, SelectTree<D> parent) {
this.data = data;
if (parent != null) {
this.parent = parent;
this.parent.getChildren().add(this);
}
}
public D getData() {
return data;
}
public void setData(D data) {
this.data = data;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public SelectTree<D> getParent() {
return parent;
}
public void setParent(SelectTree<D> parent) {
this.parent = parent;
}
public List<SelectTree<D>> getChildren() {
return children;
}
public boolean isRoot() {
return this.getParent() == null;
}
public boolean isLeaf() {
return this.getChildren() == null || this.getChildren().isEmpty();
}
}
I want to get a collection of the selected data
I want to do something like that:
public static void main(String[] args) {
SelectTree<Integer> root = generateTree();
List<Integer> selectedData = root.stream()
.peek(node -> System.out.println(node.getData()+": "+node.isSelected()))
.filter(node-> node.isSelected())
.map(node-> node.getData())
.collect(Collectors.toList()) ;
System.out.println("\nselectedData="+selectedData);
}
private static SelectTree<Integer> generateTree() {
SelectTree<Integer> n1 = new SelectTree(1, null);
SelectTree<Integer> n11 = new SelectTree(11, n1);
SelectTree<Integer> n12 = new SelectTree(12, n1);
n12.setSelected(true);
SelectTree<Integer> n111 = new SelectTree(111, n11);
n111.setSelected(true);
SelectTree<Integer> n112 = new SelectTree(112, n11);
SelectTree<Integer> n121 = new SelectTree(121, n12);
SelectTree<Integer> n122 = new SelectTree(122, n12);
return n1;
}
The problem was to find the implementation of stream() and I think I could help some people sharing my solution and I would be interested in knowing if there are some issues or better ways of doing this.
At first it was for primefaces TreeNode but I generalize the problem to all kinds of trees.
One small addition to kwisatz's answer.
This implementation:
this.getChildren().stream()
.map(SelectTree::stream)
.reduce(Stream.of(this), Stream::concat);
will be more eager, i. e. the whole hierarchy will be traversed during a stream creation. If your hirarchy is large and, let's say, you're looking for a single node matching some predicate, you may want a more lazy behaviour:
Stream.concat(Stream.of(this),
this.getChildren().stream().flatMap(SelectTree::stream));
In this case, only the children of the root node will be retrieved during a stream creation, and a search for a node won't necessarily result in the whole hierarchy being traversed.
Both approaches will exhibit the DFS iteration order.
I find this implementation of stream() which is a DFS tree traversal:
public class SelectTree<D> {
//...
public Stream<SelectTree<D>> stream() {
if (this.isLeaf()) {
return Stream.of(this);
} else {
return this.getChildren().stream()
.map(child -> child.stream())
.reduce(Stream.of(this), (s1, s2) -> Stream.concat(s1, s2));
}
}
}
If you can't change the tree implementation like for primefaces TreeNode (org.primefaces.model.TreeNode) you can define a method in an other class:
public Stream<TreeNode> stream(TreeNode parentNode) {
if(parentNode.isLeaf()) {
return Stream.of(parentNode);
} else {
return parentNode.getChildren().stream()
.map(childNode -> stream(childNode))
.reduce(Stream.of(parentNode), (s1, s2) -> Stream.concat(s1, s2)) ;
}
}
A more general approach using any node class is to add a parameter for the method, which returns the children:
public class TreeNodeStream {
public static <T> Stream<T> of(T node, Function<T, Collection<? extends T>> childrenFunction) {
return Stream.concat( //
Stream.of(node), //
childrenFunction.apply(node).stream().flatMap(n -> of(n, childrenFunction)));
}
}
An example using File:
TreeNodeStream.of(
new File("."), f -> f.isDirectory() ? Arrays.asList(f.listFiles()) :
Collections.emptySet())
.filter(f -> f.getName().endsWith(".java"))
.collect(Collectors::toList);
I have following case:
Flex class
public class Flex {
private String key;
private String val;
public Flex () {
}
public void setKey(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void setVal(String val) {
this.val = val;
}
public String getVal() {
return val;
}
FlexManager class
public class FlexManager {
private Map<String, Flex> keyValue = new HashMap<String, Flex>();
public FlexManager () {
populateFlexFieldMap();
}
private void populateFlexFieldMap() {
if (keyValue.isEmpty()) {
List<Flex> fieldds = loadKVFromFile();
for (Flexfield : fieldds) {
keyValue.put(field.getKey(), field);
}
}
}
public void setKeyValue(Map<String, FlexField> keyValue) {
this.keyValue = keyValue;
}
public Map<String, Flex> getKeyValue() {
return keyValue;
}
}
The input with managedBean is ready.
How can I get the val value in Flex class through getKeyValue() method with EL?
My approach is this: ${managedBeanName.keyValue['key'].val}
but I get this warning in my IDE
Reference ${managedBeanName.keyValue['key'].val} not found
You don't need to type get in order to invoke a getter.
${managedBeanName.keyValue['key'].val}
I'm very new to Groovy. I wonder how Closures are implemented in Groovy.
Lets say :
def a = { println "Hello" }
a()
when a() is done, what is actually happening behind the scenes? Which method does a() calls to make the closure executable?
Thanks in advance.
Basically:
your closure is a class with specific name
a() invokes doCall() which invokes doCall(Object it) (implicit it in closures)
acallsite contains method names (2 x println) - and are invoked with appropriate arguments
Here you go:
For this Groovy Script:
def a = { println "Hello"; println "Hello2" }
a()
Closure a looks like this:
class Test$_run_closure1 extends Closure
implements GeneratedClosure
{
public Object doCall(Object it)
{
CallSite acallsite[] = $getCallSiteArray();
acallsite[0].callCurrent(this, "Hello");
return acallsite[1].callCurrent(this, "Hello2");
}
public Object doCall()
{
CallSite acallsite[] = $getCallSiteArray();
return doCall(null);
}
protected MetaClass $getStaticMetaClass()
{
if(getClass() != Test$_run_closure1)
return ScriptBytecodeAdapter.initMetaClass(this);
ClassInfo classinfo = $staticClassInfo;
if(classinfo == null)
$staticClassInfo = classinfo = ClassInfo.getClassInfo(getClass());
return classinfo.getMetaClass();
}
public static void __$swapInit()
{
CallSite acallsite[] = $getCallSiteArray();
$callSiteArray = null;
}
private static void $createCallSiteArray_1(String as[])
{
as[0] = "println";
as[1] = "println";
}
private static CallSiteArray $createCallSiteArray()
{
String as[] = new String[2];
$createCallSiteArray_1(as);
return new CallSiteArray(Test$_run_closure1, as);
}
private static CallSite[] $getCallSiteArray()
{
CallSiteArray callsitearray;
if($callSiteArray == null || (callsitearray = (CallSiteArray)$callSiteArray.get()) == null)
{
callsitearray = $createCallSiteArray();
$callSiteArray = new SoftReference(callsitearray);
}
return callsitearray.array;
}
static Class _mthclass$(String s)
{
try
{
return Class.forName(s);
}
catch(ClassNotFoundException classnotfoundexception)
{
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
private static ClassInfo $staticClassInfo;
public static transient boolean __$stMC;
private static SoftReference $callSiteArray;
static
{
__$swapInit();
}
public Test$_run_closure1(Object _outerInstance, Object _thisObject)
{
CallSite acallsite[] = $getCallSiteArray();
super(_outerInstance, _thisObject);
}
}
It ends up calling one of the Closure.call methods (in this case the one with no args)
There's more info about this in the documentation