All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.escalon.hypermedia.ResourceTraversal Maven / Gradle / Ivy

There is a newer version: 0.4.2
Show newest version
package de.escalon.hypermedia;

import de.escalon.hypermedia.affordance.DataType;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.ResourceSupport;
import org.springframework.hateoas.Resources;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.*;

/**
 * Created by Dietrich on 07.05.2016.
 */
public class ResourceTraversal {

    static final Set FILTER_RESOURCE_SUPPORT = new HashSet(Arrays.asList("class", "links", "id"));

    static class NullValue {

    }
    public static final NullValue NULL_VALUE = new NullValue();


    public void traverseResource(ResourceSupportVisitor visitor, Object object) {
        Set filtered = FILTER_RESOURCE_SUPPORT;
        if (object == null) {
            return;
        }

        try {
            // TODO: move all returns to else branch of property descriptor handling
            if (object instanceof Resource) {
                Resource resource = (Resource) object;

                if(!visitor.visitLinks(resource.getLinks())) {
                    return;
                }
                traverseResource(visitor, resource.getContent());
                return;
            } else if (object instanceof Resources) {
                Resources resources = (Resources) object;
                if(!visitor.visitLinks(resources.getLinks())) {
                    return;
                }
                traverseResource(visitor, resources.getContent());
                return;
            } else if (object instanceof ResourceSupport) {
                ResourceSupport resource = (ResourceSupport) object;
                if(!visitor.visitLinks(resource.getLinks())) {
                    return;
                }
                // wrap object attributes below to avoid endless loop
            } else if (object instanceof Collection) {
                Collection collection = (Collection) object;
                if(!visitor.visitEnterCollection(collection)) {
                    return;
                }
                for (Object item : collection) {
                    traverseResource(visitor, item);
                }
                if(!visitor.visitLeaveCollection(collection)) {
                    return;
                }
                return;
            }
            if (object instanceof Map) {
                Map map = (Map) object;
                for (Map.Entry entry : map.entrySet()) {
                    String key = entry.getKey()
                            .toString();
                    Object content = entry.getValue();
                    Object value = getContentAsScalarValue(content);
//                    UberNode entryNode = new UberNode();
//                    objectNode.addData(entryNode);
//                    entryNode.setName(key);
//                    if (value != null) {
//                        entryNode.setValue(value);
//                    } else {
//                        traverseResource(visitor, content);
//                    }

                    Class type = content != null ? content.getClass() : null;
                    if(!visitor.visitEnterProperty(key, type, value)) {
                        return;
                    }
                    if (value != null) {
                        // for each scalar property of a simple bean, add valuepair nodes to data
                        if(!visitor.visitProperty(key, type, value)) {
                            return;
                        }
                    } else {
                        traverseResource(visitor, content);
                    }
                    if(!visitor.visitLeaveProperty(key, type, value)) {
                        return;
                    }
                }
            } else {
                Map propertyDescriptors = PropertyUtils.getPropertyDescriptors(object);
                for (PropertyDescriptor propertyDescriptor : propertyDescriptors.values()) {
                    String name = propertyDescriptor.getName();
                    if (filtered.contains(name)) {
                        continue;
                    }

//                    UberNode propertyNode = new UberNode();
                    Object content = propertyDescriptor.getReadMethod()
                            .invoke(object);
//
//                    if (isEmptyCollectionOrMap(content, propertyDescriptor.getPropertyType())) {
//                        continue;
//                    }
//
                    Object value = getContentAsScalarValue(content);
//                    propertyNode.setName(name);
//                    objectNode.addData(propertyNode);
                    Class propertyType = propertyDescriptor.getPropertyType();
                    if(!visitor.visitEnterProperty(name, propertyType, value)) {
                        return;
                    }
                    if (value != null) {
                        // for each scalar property of a simple bean, add valuepair nodes to data
                        if(!visitor.visitProperty(name, propertyType, value)) {
                            return;
                        }
                    } else {
                        traverseResource(visitor, content);
                    }
                    if(!visitor.visitLeaveProperty(name, propertyType, value)) {
                        return;
                    }
                }

                Field[] fields = object.getClass()
                        .getFields();
                for (Field field : fields) {
                    String name = field.getName();
                    if (!propertyDescriptors.containsKey(name)) {
                        Object content = field.get(object);
                        Class type = field.getType();
//                        if (isEmptyCollectionOrMap(content, type)) {
//                            continue;
//                        }
//                        UberNode propertyNode = new UberNode();
//
                        Object value = getContentAsScalarValue(content);
//                        propertyNode.setName(name);
//                        objectNode.addData(propertyNode);
//                        if (value != null) {
//                            // for each scalar property of a simple bean, add valuepair nodes to data
//                            propertyNode.setValue(value);
//                        } else {
//                            toUberData(propertyNode, content);
//                        }

                        if(!visitor.visitEnterProperty(name, type, value)) {
                            return;
                        }
                        if (value != null) {
                            // for each scalar property of a simple bean, add valuepair nodes to data
                            if(!visitor.visitProperty(name, type, value)) {
                                return;
                            }
                        } else {
                            traverseResource(visitor, content);
                        }
                        if(!visitor.visitLeaveProperty(name, type, value)) {
                            return;
                        }

                    }
                }
            }
        } catch (Exception ex) {
            throw new RuntimeException("failed to transform object " + object, ex);
        }
    }

    private static Object getContentAsScalarValue(Object content) {
        final Object value;
        if (content == null) {
            value = ResourceTraversal.NULL_VALUE;
        } else if (DataType.isSingleValueType(content.getClass())) {
            value = content.toString();
        } else {
            value = null;
        }
        return value;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy