OccurrenceConcrete.java

106 lines | 3.792 kB Blame History Raw Download
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufrgs.inf.prosoft.memoizeit;

import br.ufrgs.inf.prosoft.memoizeit.graph.Node;
import br.ufrgs.inf.prosoft.memoizeit.utils.Action;
import br.ufrgs.inf.prosoft.memoizeit.utils.ObjectUtils;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 *
 * @author romulo
 */
public class OccurrenceConcrete extends Occurrence {

    private final Object returnValue;
    private final List<Parameter> parameters;
    private boolean truncated;

    public OccurrenceConcrete(String instance, Object returnValue, List<Parameter> parameters, long startTime, long endTime) {
        super(instance, startTime, endTime);
        this.returnValue = returnValue;
        this.parameters = parameters;
        this.truncated = true;
    }

    @Override
    public Object getReturnValue() {
        return this.returnValue;
    }

    @Override
    public List<Parameter> getParameters() {
        return this.parameters;
    }

    private void removeUnusedFields(Map<String, Object> map, String parameterType, Node<String> methodNode) {
        if (map == null) {
            return;
        }
        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            String getter = parameterType + ".get" + entry.getKey().substring(0, 1).toUpperCase() + entry.getKey().substring(1);
            if (!methodNode.getLinks().stream().anyMatch(node -> node.getContent().equals(getter))) {
                iterator.remove();
            }
        }

    }

    @Override
    protected Occurrence removeUnusedFields(Node<String> methodNode) {
        getParameters().stream().parallel().forEach((parameter) -> {
            String parameterType = parameter.getType();
            if (parameter.getData() instanceof Collection) {
                Collection collection = (Collection) parameter.getData();
                if (!collection.isEmpty() && collection.stream().filter(Objects::nonNull).findAny().get() instanceof Map) {
                    Collection<Map<String, Object>> cast = collection;
                    cast.forEach(map -> removeUnusedFields(map, parameterType, methodNode));
                }
            } else if (parameter.getData() instanceof Map) {
                Map<String, Object> map = (Map<String, Object>) parameter.getData();
                removeUnusedFields(map, parameterType, methodNode);
            }
        });
        return this;
    }

    @Override
    protected OccurrenceConcrete getView(int depth) {
        if (!this.truncated) {
            return this;
        }
        this.truncated = false;
        if (depth > 512) {
            return this;
        }
        Object returnValue = ObjectUtils.deepCopy(this.returnValue);
        Action onTruncate = () -> {
            this.truncated = true;
        };
        ObjectUtils.truncateObject(returnValue, depth, onTruncate);
        List<Parameter> parameters = this.parameters.stream()
                .map(parameter -> {
                    Object parameterView = ObjectUtils.deepCopy(parameter.getData());
                    ObjectUtils.truncateObject(parameterView, depth, onTruncate);
                    return new Parameter(parameter.getType(), parameterView);
                }).collect(Collectors.toList());
        if (!this.truncated) {
            return this;
        }
        OccurrenceConcrete occurrenceConcrete = new OccurrenceConcrete(getInstance(), returnValue, parameters, getStartTime(), getEndTime());
        return occurrenceConcrete;
    }

}