Search in sources :

Example 1 with AttributeKey

use of org.keycloak.client.registration.cli.common.AttributeKey in project keycloak by keycloak.

the class ReflectionUtil method resolveField.

public static Field resolveField(Class type, AttributeKey attr) {
    Field f = null;
    Type gtype = type;
    for (AttributeKey.Component c : attr.getComponents()) {
        if (f != null) {
            gtype = f.getGenericType();
            if (gtype instanceof ParameterizedType) {
                Type[] typeargs = ((ParameterizedType) gtype).getActualTypeArguments();
                if (typeargs.length > 0) {
                    gtype = typeargs[typeargs.length - 1];
                }
            }
        }
        Map<String, Field> fields = getAttrFieldsForType(gtype);
        f = fields.get(c.getName());
        if (f == null) {
            throw new AttributeException(attr.toString(), "No such attribute: " + attr);
        }
    }
    return f;
}
Also used : AttributeKey(org.keycloak.client.registration.cli.common.AttributeKey) ParameterizedType(java.lang.reflect.ParameterizedType) Field(java.lang.reflect.Field) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type)

Example 2 with AttributeKey

use of org.keycloak.client.registration.cli.common.AttributeKey in project keycloak by keycloak.

the class ReflectionUtilTest method testKeyParsing.

@Test
public void testKeyParsing() {
    assertAttributeKey(new AttributeKey("am.bam.pet"), "am", -1, "bam", -1, "pet", -1);
    assertAttributeKey(new AttributeKey("a"), "a", -1);
    assertAttributeKey(new AttributeKey("a.b"), "a", -1, "b", -1);
    assertAttributeKey(new AttributeKey("a.b[1]"), "a", -1, "b", 1);
    assertAttributeKey(new AttributeKey("a[12].b"), "a", 12, "b", -1);
    assertAttributeKey(new AttributeKey("a[10].b[20]"), "a", 10, "b", 20);
    assertAttributeKey(new AttributeKey("\"am\".\"bam\".\"pet\""), "am", -1, "bam", -1, "pet", -1);
    assertAttributeKey(new AttributeKey("\"am\".bam.\"pet\""), "am", -1, "bam", -1, "pet", -1);
    assertAttributeKey(new AttributeKey("\"am.bam\".\"pet\""), "am.bam", -1, "pet", -1);
    assertAttributeKey(new AttributeKey("\"am.bam[2]\".\"pet[6]\""), "am.bam", 2, "pet", 6);
    try {
        new AttributeKey("a.");
        Assert.fail("Should have failed");
    } catch (RuntimeException expected) {
    }
    try {
        new AttributeKey("a[]");
        Assert.fail("Should have failed");
    } catch (RuntimeException expected) {
    }
    try {
        new AttributeKey("a[lala]");
        Assert.fail("Should have failed");
    } catch (RuntimeException expected) {
    }
    try {
        new AttributeKey("a[\"lala\"]");
        Assert.fail("Should have failed");
    } catch (RuntimeException expected) {
    }
    try {
        new AttributeKey(".a");
        Assert.fail("Should have failed");
    } catch (RuntimeException expected) {
    }
    try {
        new AttributeKey("\"am\"..\"bam\".\"pet\"");
        Assert.fail("Should have failed");
    } catch (RuntimeException expected) {
    }
    try {
        new AttributeKey("\"am\"ups.\"bam\".\"pet\"");
        Assert.fail("Should have failed");
    } catch (RuntimeException expected) {
    }
    try {
        new AttributeKey("ups\"am\"ups.\"bam\".\"pet\"");
        Assert.fail("Should have failed");
    } catch (RuntimeException expected) {
    }
}
Also used : AttributeKey(org.keycloak.client.registration.cli.common.AttributeKey) Test(org.junit.Test)

Example 3 with AttributeKey

use of org.keycloak.client.registration.cli.common.AttributeKey in project keycloak by keycloak.

the class ReflectionUtilTest method testListAttributes.

@Ignore
@Test
public void testListAttributes() {
    LinkedHashMap<String, String> items = null;
    /*
        items = getAttributeListWithJSonTypes(Data.class, new AttributeKey(""));

        for (Map.Entry<String, String> item: items.entrySet()) {
            System.out.printf("%-40s %s\n", item.getKey(), item.getValue());
        }
*/
    /*
        System.out.println("\n-- nested ------------------------\n");

        items = getAttributeListWithJSonTypes(Data.class, new AttributeKey("nested"));
        for (Map.Entry<String, String> item: items.entrySet()) {
            System.out.printf("%-40s %s\n", item.getKey(), item.getValue());
        }
*/
    System.out.println("\n-- dataList ----------------------\n");
    items = ReflectionUtil.getAttributeListWithJSonTypes(Data.class, new AttributeKey("dataList"));
    for (Map.Entry<String, String> item : items.entrySet()) {
        System.out.printf("%-40s %s\n", item.getKey(), item.getValue());
    }
    if (items.size() == 0) {
        Field f = ReflectionUtil.resolveField(Data.class, new AttributeKey("dataList"));
        String ts = ReflectionUtil.getTypeString(null, f);
        Type t = f.getGenericType();
        if ((List.class.isAssignableFrom(f.getType()) || f.getType().isArray()) && t instanceof ParameterizedType) {
            System.out.printf("%s, where object is:\n", ts);
        }
        t = ((ParameterizedType) t).getActualTypeArguments()[0];
        if (t instanceof Class) {
            items = ReflectionUtil.getAttributeListWithJSonTypes((Class) t, null);
            for (Map.Entry<String, String> item : items.entrySet()) {
                System.out.printf("   %-37s %s\n", item.getKey(), item.getValue());
            }
        }
    }
}
Also used : AttributeKey(org.keycloak.client.registration.cli.common.AttributeKey) ParameterizedType(java.lang.reflect.ParameterizedType) Field(java.lang.reflect.Field) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) List(java.util.List) LinkedList(java.util.LinkedList) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 4 with AttributeKey

use of org.keycloak.client.registration.cli.common.AttributeKey in project keycloak by keycloak.

the class ReflectionUtil method getAttributeListWithJSonTypes.

public static LinkedHashMap<String, String> getAttributeListWithJSonTypes(Class type, AttributeKey attr) {
    LinkedHashMap<String, String> result = new LinkedHashMap<>();
    attr = attr != null ? attr : new AttributeKey();
    Map<String, Field> fields = getAttrFieldsForType(type);
    for (AttributeKey.Component c : attr.getComponents()) {
        Field f = fields.get(c.getName());
        if (f == null) {
            throw new AttributeException(attr.toString(), "No such attribute: " + attr);
        }
        type = f.getType();
        if (isBasicType(type) || isListType(type) || isMapType(type)) {
            return result;
        } else {
            fields = getAttrFieldsForType(type);
        }
    }
    for (Map.Entry<String, Field> item : fields.entrySet()) {
        String key = item.getKey();
        Class clazz = item.getValue().getType();
        String t = getTypeString(clazz, item.getValue());
        result.put(key, t);
    }
    return result;
}
Also used : AttributeKey(org.keycloak.client.registration.cli.common.AttributeKey) Field(java.lang.reflect.Field) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap)

Example 5 with AttributeKey

use of org.keycloak.client.registration.cli.common.AttributeKey in project keycloak by keycloak.

the class ReflectionUtil method setAttributes.

public static void setAttributes(Object client, List<AttributeOperation> attrs) {
    for (AttributeOperation item : attrs) {
        AttributeKey attr = item.getKey();
        Object nested = client;
        List<AttributeKey.Component> cs = attr.getComponents();
        for (int i = 0; i < cs.size(); i++) {
            AttributeKey.Component c = cs.get(i);
            Class type = nested.getClass();
            Field field = null;
            if (!isMapType(type)) {
                Map<String, Field> fields = getAttrFieldsForType(type);
                if (fields == null) {
                    throw new AttributeException(attr.toString(), "Unexpected condition - unknown type: " + type);
                }
                field = fields.get(c.getName());
                Class parent = type;
                while (field == null) {
                    parent = parent.getSuperclass();
                    if (parent == Object.class) {
                        throw new AttributeException(attr.toString(), "Unknown attribute '" + c.getName() + "' on " + client.getClass());
                    }
                    fields = getAttrFieldsForType(parent);
                    field = fields.get(c.getName());
                }
            }
            // if it's a 'basic' type we directly use setter
            type = field == null ? type : field.getType();
            if (isBasicType(type)) {
                if (i < cs.size() - 1) {
                    throw new AttributeException(attr.toString(), "Attribute is of primitive type, and can't be nested further: " + c);
                }
                try {
                    Object val = convertValueToType(item.getValue(), type);
                    field.set(nested, val);
                } catch (Exception e) {
                    throw new AttributeException(attr.toString(), "Failed to set attribute " + attr, e);
                }
            } else if (isListType(type)) {
                if (i < cs.size() - 1) {
                    // not the target component
                    try {
                        nested = field.get(nested);
                    } catch (Exception e) {
                        throw new AttributeException(attr.toString(), "Failed to get attribute \"" + c + "\" in " + attr, e);
                    }
                    if (c.getIndex() >= 0) {
                        // list item
                        // get idx-th item
                        List l = (List) nested;
                        if (c.getIndex() >= l.size()) {
                            throw new AttributeException(attr.toString(), "Array index out of bounds for \"" + c + "\" in " + attr);
                        }
                        nested = l.get(c.getIndex());
                    }
                } else {
                    // target component
                    Class itype = type;
                    Type gtype = field.getGenericType();
                    if (gtype instanceof ParameterizedType) {
                        Type[] typeArgs = ((ParameterizedType) gtype).getActualTypeArguments();
                        if (typeArgs.length >= 1 && typeArgs[0] instanceof Class) {
                            itype = (Class) typeArgs[0];
                        } else {
                            itype = String.class;
                        }
                    }
                    if (c.getIndex() >= 0 || attr.isAppend()) {
                        // some list item
                        // get the list first
                        List target;
                        try {
                            target = (List) field.get(nested);
                        } catch (Exception e) {
                            throw new AttributeException(attr.toString(), "Failed to get list attribute: " + attr, e);
                        }
                        // now replace or add idx-th item
                        if (target == null) {
                            target = createNewList(type);
                            try {
                                field.set(nested, target);
                            } catch (Exception e) {
                                throw new AttributeException(attr.toString(), "Failed to set list attribute " + attr, e);
                            }
                        }
                        if (c.getIndex() >= target.size()) {
                            throw new AttributeException(attr.toString(), "Array index out of bounds for \"" + c + "\" in " + attr);
                        }
                        if (attr.isAppend()) {
                            try {
                                Object value = convertValueToType(item.getValue(), itype);
                                if (c.getIndex() >= 0) {
                                    target.add(c.getIndex(), value);
                                } else {
                                    target.add(value);
                                }
                            } catch (Exception e) {
                                throw new AttributeException(attr.toString(), "Failed to set list attribute " + attr, e);
                            }
                        } else {
                            if (item.getType() == AttributeOperation.Type.SET) {
                                try {
                                    Object value = convertValueToType(item.getValue(), itype);
                                    target.set(c.getIndex(), value);
                                } catch (Exception e) {
                                    throw new AttributeException(attr.toString(), "Failed to set list attribute " + attr, e);
                                }
                            } else {
                                try {
                                    target.remove(c.getIndex());
                                } catch (Exception e) {
                                    throw new AttributeException(attr.toString(), "Failed to remove list attribute " + attr, e);
                                }
                            }
                        }
                    } else {
                        // set the whole list field itself
                        List value = createNewList(type);
                        ;
                        if (item.getType() == AttributeOperation.Type.SET) {
                            List converted = convertValueToList(item.getValue(), itype);
                            value.addAll(converted);
                        }
                        try {
                            field.set(nested, value);
                        } catch (Exception e) {
                            throw new AttributeException(attr.toString(), "Failed to set list attribute " + attr, e);
                        }
                    }
                }
            } else {
                // object type
                if (i < cs.size() - 1) {
                    // not the target component
                    Object value;
                    if (field == null) {
                        if (isMapType(nested.getClass())) {
                            value = ((Map) nested).get(c.getName());
                        } else {
                            throw new RuntimeException("Unexpected condition while processing: " + attr);
                        }
                    } else {
                        try {
                            value = field.get(nested);
                        } catch (Exception e) {
                            throw new AttributeException(attr.toString(), "Failed to get attribute \"" + c + "\" in " + attr, e);
                        }
                    }
                    if (value == null) {
                        // create the target attribute
                        if (isMapType(nested.getClass())) {
                            throw new RuntimeException("Creating nested object trees not supported");
                        } else {
                            try {
                                value = createNewObject(type);
                                field.set(nested, value);
                            } catch (Exception e) {
                                throw new AttributeException(attr.toString(), "Failed to set attribute " + attr, e);
                            }
                        }
                    }
                    nested = value;
                } else {
                    // todo implement map put
                    if (isMapType(nested.getClass())) {
                        try {
                            ((Map) nested).put(c.getName(), item.getValue());
                        } catch (Exception e) {
                            throw new AttributeException(attr.toString(), "Failed to set map key " + attr, e);
                        }
                    } else {
                        try {
                            Object value = convertValueToType(item.getValue(), type);
                            field.set(nested, value);
                        } catch (Exception e) {
                            throw new AttributeException(attr.toString(), "Failed to set attribute " + attr, e);
                        }
                    }
                }
            }
        }
    }
}
Also used : AttributeOperation(org.keycloak.client.registration.cli.common.AttributeOperation) IOException(java.io.IOException) JsonParseException(com.fasterxml.jackson.core.JsonParseException) AttributeKey(org.keycloak.client.registration.cli.common.AttributeKey) ParameterizedType(java.lang.reflect.ParameterizedType) Field(java.lang.reflect.Field) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Aggregations

AttributeKey (org.keycloak.client.registration.cli.common.AttributeKey)6 Field (java.lang.reflect.Field)5 ParameterizedType (java.lang.reflect.ParameterizedType)4 Type (java.lang.reflect.Type)4 LinkedHashMap (java.util.LinkedHashMap)4 Map (java.util.Map)4 HashMap (java.util.HashMap)3 LinkedList (java.util.LinkedList)2 List (java.util.List)2 Test (org.junit.Test)2 JsonParseException (com.fasterxml.jackson.core.JsonParseException)1 IOException (java.io.IOException)1 PrintStream (java.io.PrintStream)1 ArrayList (java.util.ArrayList)1 Ignore (org.junit.Ignore)1 AttributeOperation (org.keycloak.client.registration.cli.common.AttributeOperation)1 EndpointType (org.keycloak.client.registration.cli.common.EndpointType)1 ReflectionUtil.isBasicType (org.keycloak.client.registration.cli.util.ReflectionUtil.isBasicType)1 ReflectionUtil.isListType (org.keycloak.client.registration.cli.util.ReflectionUtil.isListType)1 ReflectionUtil.isMapType (org.keycloak.client.registration.cli.util.ReflectionUtil.isMapType)1