package org.smoothbuild.db.outputs; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import org.smoothbuild.db.hashed.HashedDb; import org.smoothbuild.db.hashed.Marshaller; import org.smoothbuild.db.hashed.Unmarshaller; import org.smoothbuild.db.values.ValuesDb; import org.smoothbuild.lang.message.ErrorMessage; import org.smoothbuild.lang.message.InfoMessage; import org.smoothbuild.lang.message.Message; import org.smoothbuild.lang.message.Messages; import org.smoothbuild.lang.message.WarningMessage; import org.smoothbuild.lang.type.Type; import org.smoothbuild.lang.type.Types; import org.smoothbuild.lang.value.SString; import org.smoothbuild.lang.value.Value; import org.smoothbuild.task.base.Output; import com.google.common.collect.ImmutableList; import com.google.common.hash.HashCode; public class OutputsDb { private final HashedDb hashedDb; private final ValuesDb valuesDb; @Inject public OutputsDb(@Outputs HashedDb hashedDb, ValuesDb valuesDb) { this.hashedDb = hashedDb; this.valuesDb = valuesDb; } public void write(HashCode taskHash, Output output) { Marshaller marshaller = hashedDb.newMarshaller(taskHash); ImmutableList<Message> messages = output.messages(); marshaller.writeInt(messages.size()); for (Message message : messages) { SString messageString = valuesDb.string(message.getMessage()); marshaller.writeInt(messageTypeToInt(message)); marshaller.writeHash(messageString.hash()); } if (!Messages.containsErrors(messages)) { marshaller.writeHash(output.result().hash()); } marshaller.close(); } public boolean contains(HashCode taskHash) { return hashedDb.contains(taskHash); } public Output read(HashCode taskHash, Type type) { try (Unmarshaller unmarshaller = hashedDb.newUnmarshaller(taskHash)) { int size = unmarshaller.readInt(); List<Message> messages = new ArrayList<>(); for (int i = 0; i < size; i++) { int messageType = unmarshaller.readInt(); HashCode messageStringHash = unmarshaller.readHash(); SString messageSString = (SString) valuesDb.read(Types.STRING, messageStringHash); String messageString = messageSString.value(); messages.add(newMessage(messageType, messageString)); } if (Messages.containsErrors(messages)) { return new Output(messages); } else { HashCode resultObjectHash = unmarshaller.readHash(); Value value = valuesDb.read(type, resultObjectHash); return new Output(value, messages); } } } private static int messageTypeToInt(Message message) { if (message instanceof ErrorMessage) { return 0; } if (message instanceof WarningMessage) { return 1; } if (message instanceof InfoMessage) { return 2; } throw new RuntimeException("Unsupported Message type: " + message.getClass() .getCanonicalName()); } private static Message newMessage(int type, String message) { if (type == 0) { return new ErrorMessage(message); } if (type == 1) { return new WarningMessage(message); } if (type == 2) { return new InfoMessage(message); } throw new RuntimeException("Illegal message type. Outputs DB corrupted?"); } }