TraceReader.java

149 lines | 5.837 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.trace.reader;

import br.ufrgs.inf.prosoft.trace.Parameter;
import br.ufrgs.inf.prosoft.trace.Return;
import br.ufrgs.inf.prosoft.trace.Trace;
import br.ufrgs.inf.prosoft.trace.TraceConcrete;
import br.ufrgs.inf.prosoft.trace.TraceReference;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 *
 * @author romulo
 */
public class TraceReader {

    private static final Logger logger = Logger.getLogger(TraceReader.class.getName());

    public static List<Trace> partiallyParseFile(String path) {
        Traces.PATH = path;
        return parseFile(path, Mode.PARTIAL);
    }

    public static List<Trace> hashedParseFile(String path) {
        return parseFile(path, Mode.HASHED);
    }

    public static List<Trace> parseFile(String path) {
        return parseFile(path, Mode.COMPLETE);
    }

    public static String getLineCount(String path) throws IOException {
        try {
            Process process = Runtime.getRuntime().exec("wc -l " + path);
            Thread.sleep(2000);
            if (process.isAlive()) {
                return "timeout";
            }
            InputStream inputStream = process.getInputStream();
            StringBuilder count = new StringBuilder();
            int c;
            while (true) {
                c = inputStream.read();
                if (c == 32 || c == -1 || c == 10) {
                    break;
                }
                count.append((char) c);
            }
            return count.toString();
        } catch (Exception ex) {
            return ex.getMessage();
        }
    }

    private static List<Trace> parseFile(String path, Mode mode) {
        List<Trace> traces = new ArrayList<>();
        try {
            logger.log(Level.INFO, "Parsing {0} traces", getLineCount(path));
            try (Stream<String> lines = Files.lines(Paths.get(path))) {
                Gson gson = new GsonBuilder().setLenient().create();
                lines.forEach(new Consumer<String>() {
                    private int index = 0;
                    private MessageDigest messageDigest;

                    {
                        try {
                            this.messageDigest = MessageDigest.getInstance("sha-512");
                        } catch (NoSuchAlgorithmException ex) {
                        }
                    }

                    private String digest(java.lang.Object object) {
                        return String.valueOf(messageDigest.digest(String.valueOf(object).getBytes()));
                    }

                    @Override
                    public void accept(String line) {
                        try {
                            Trace trace;
                            switch (mode) {
                                case PARTIAL:
                                    trace = gson.fromJson(line, TraceReference.class);
                                    ((TraceReference) trace).setIndex(index);
                                    break;
                                case HASHED:
                                    trace = gson.fromJson(line, TraceConcrete.class);
                                    trace = new TraceConcrete(trace.getInstance(), trace.getModifiers(),
                                            new Return(trace.getReturn().getType(), digest(trace.getReturn().getData())),
                                            trace.getName(),
                                            trace.getParameters().stream()
                                                    .map(parameter -> new Parameter(parameter.getType(), digest(parameter.getData())))
                                                    .collect(Collectors.toList()),
                                            trace.getStartTime(), trace.getEndTime(), trace.getUserSession());
                                    break;
                                default:
                                    trace = gson.fromJson(line, TraceConcrete.class);
                                    break;
                            }
                            traces.add(trace);
                            String verbose = System.getenv("TRACER_VERBOSE");
                            if (verbose == null) {
                                verbose = "false";
                            }
                            if (verbose.equals("true")) {
                                System.out.print(".");
                                System.out.flush();
                                if (index != 0 && index % 100 == 0) {
                                    System.out.println();
                                }
                            }
                        } catch (JsonSyntaxException e) {
                            if (line.length() > 200) {
                                line = line.substring(0, 200);
                            }
                            logger.log(Level.INFO, "Malformed Trace {0}: {1}", new java.lang.Object[]{index, line});
                        } finally {
                            index++;
                        }
                    }
                });
                System.out.println();
            }
        } catch (IOException ex) {
            logger.log(Level.SEVERE, null, ex);
        }
        return traces;
    }

}