/*
* Grapht, an open source dependency injector.
* Copyright 2014-2015 various contributors (see CONTRIBUTORS.txt)
* Copyright 2010-2014 Regents of the University of Minnesota
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.grouplens.grapht.graph;
import org.grouplens.grapht.BindingFunctionBuilder;
import org.grouplens.grapht.BindingFunctionBuilder.RuleSet;
import org.grouplens.grapht.Dependency;
import org.grouplens.grapht.annotation.AnnotationBuilder;
import org.grouplens.grapht.CachePolicy;
import org.grouplens.grapht.Component;
import org.grouplens.grapht.reflect.Desires;
import org.grouplens.grapht.reflect.Satisfactions;
import org.grouplens.grapht.reflect.internal.InstanceSatisfaction;
import org.grouplens.grapht.reflect.internal.types.NamedType;
import org.grouplens.grapht.solver.DefaultDesireBindingFunction;
import org.grouplens.grapht.solver.DependencySolver;
import org.grouplens.grapht.solver.DesireChain;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import javax.inject.Named;
import java.io.*;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
public class SerializationTest {
private static File GRAPH_FILE = new File("graph.dump");
@Test
public void testEmptyGraph() throws Exception {
DAGNode<Component, DesireChain> g =
DAGNode.singleton(DependencySolver.ROOT_SATISFACTION);
write(g);
DAGNode<Component, DesireChain> read = read();
assertThat(read.getReachableNodes(),
contains(read));
}
@Test
public void testSharedNodesGraph() throws Exception {
Component s1 = Component.create(Satisfactions.type(Object.class), CachePolicy.NEW_INSTANCE);
Component s2 = Component.create(Satisfactions.type(Object.class), CachePolicy.MEMOIZE);
DAGNode<Component, String> n2 = DAGNode.singleton(s2);
DAGNodeBuilder<Component, String> bld = DAGNode.newBuilder(s1);
bld.addEdge(n2, "wombat");
bld.addEdge(n2, "foobar");
write(bld.build());
DAGNode<Object, Object> read = read();
Assert.assertEquals(2, read.getReachableNodes().size());
assertThat(read.getOutgoingEdges(),
hasSize(2));
}
@Test
public void testDependencySolverSerialization() throws Exception {
BindingFunctionBuilder b = new BindingFunctionBuilder();
b.getRootContext().bind(String.class).withQualifier(new AnnotationBuilder<Named>(Named.class).set("value", "unused").build()).to("shouldn't see this"); // extra binding to make sure it's skipped
b.getRootContext().bind(String.class).withQualifier(new AnnotationBuilder<Named>(Named.class).set("value", "test1").build()).to("hello world");
DependencySolver solver = DependencySolver.newBuilder()
.addBindingFunction(b.build(RuleSet.EXPLICIT))
.addBindingFunction(b.build(RuleSet.INTERMEDIATE_TYPES))
.addBindingFunction(b.build(RuleSet.SUPER_TYPES))
.addBindingFunction(DefaultDesireBindingFunction.create())
.build();
solver.resolve(Desires.create(null, NamedType.class, false));
DAGNode<Component,Dependency> g = solver.getGraph();
write(g);
DAGNode<Component, Dependency> root = read();
Assert.assertEquals(1, root.getOutgoingEdges().size());
DAGEdge<Component, Dependency> rootEdge = root.getOutgoingEdges().iterator().next();
DAGNode<Component, Dependency> namedType = rootEdge.getTail();
Assert.assertEquals(NamedType.class, namedType.getLabel().getSatisfaction().getErasedType());
Assert.assertEquals(NamedType.class, rootEdge.getLabel().getInitialDesire().getDesiredType());
Assert.assertEquals(rootEdge.getLabel().getInitialDesire().getSatisfaction(), namedType.getLabel().getSatisfaction());
Assert.assertNull(rootEdge.getLabel().getInitialDesire().getInjectionPoint().getQualifier());
Assert.assertTrue(rootEdge.getLabel().getInitialDesire().getInjectionPoint().getAttributes().isEmpty());
Assert.assertEquals(1, namedType.getOutgoingEdges().size());
DAGEdge<Component, Dependency> nameEdge = namedType.getOutgoingEdges().iterator().next();
DAGNode<Component, Dependency> string = nameEdge.getTail();
Assert.assertEquals(String.class, string.getLabel().getSatisfaction().getErasedType());
Assert.assertEquals(String.class, nameEdge.getLabel().getInitialDesire().getDesiredType());
Assert.assertEquals(AnnotationBuilder.of(Named.class).setValue("test1").build(), nameEdge.getLabel().getInitialDesire().getInjectionPoint().getQualifier());
Assert.assertTrue(nameEdge.getLabel().getInitialDesire().getInjectionPoint().getAttributes().isEmpty());
Assert.assertTrue(string.getLabel().getSatisfaction() instanceof InstanceSatisfaction);
Assert.assertEquals("hello world", ((InstanceSatisfaction) string.getLabel().getSatisfaction()).getInstance());
}
@After
public void cleanup() throws Exception {
GRAPH_FILE.delete();
}
private <V, E> void write(DAGNode<V, E> g) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(GRAPH_FILE));
out.writeObject(g);
out.flush();
out.close();
}
private <V,E> DAGNode<V,E> read() throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(GRAPH_FILE));
try {
DAGNode<V,E> g = (DAGNode<V,E>) in.readObject();
return g;
} finally {
in.close();
}
}
}