private static void detectCircularDependencies(Collection<Binding<?>> bindings, List<Binding<?>> path) { for (Binding<?> binding : bindings) { if (binding.isCycleFree()) { continue; } if (binding.isVisiting()) { int index = path.indexOf(binding); StringBuilder message = new StringBuilder() .append("Dependency cycle:"); for (int i = index; i < path.size(); i++) { message.append("\n ").append(i - index).append(". ") .append(path.get(i).provideKey).append(" bound by ").append(path.get(i)); } message.append("\n ").append(0).append(". ").append(binding.provideKey); throw new IllegalStateException(message.toString()); } binding.setVisiting(true); path.add(binding); try { ArraySet<Binding<?>> dependencies = new ArraySet<Binding<?>>(); binding.getDependencies(dependencies, dependencies); detectCircularDependencies(dependencies, path); binding.setCycleFree(true); } finally { path.remove(path.size() - 1); binding.setVisiting(false); } } }
@Override public String toString() { return "@Singleton/" + binding.toString(); } }
@SuppressWarnings("unchecked") // onlyInstance is either 'UNINITIALIZED' or a 'T'. @Override public T get() { if (onlyInstance == UNINITIALIZED) { synchronized (this) { if (onlyInstance == UNINITIALIZED) { onlyInstance = binding.get(); } } } return (T) onlyInstance; }
@Override public void injectMembers(T t) { try { for (int i = 0; i < fields.length; i++) { fields[i].set(t, fieldBindings[i].get()); } if (supertypeBinding != null) { supertypeBinding.injectMembers(t); } } catch (IllegalAccessException e) { throw new AssertionError(e); } }
binding = linker.bindings.get(key); if (binding != null) { if (linker != this && !binding.isLinked()) throw new AssertionError(); break; deferredBinding.setLibrary(library); deferredBinding.setDependedOn(true); toLink.add(deferredBinding); attachSuccess = false; if (!binding.isLinked()) { binding.setLibrary(library); binding.setDependedOn(true); return binding;
Binding<?> resolvedBinding = createBinding(key, binding.requiredBy, deferred.classLoader, mustHaveInjections); resolvedBinding.setLibrary(binding.library()); resolvedBinding.setDependedOn(binding.dependedOn()); binding.attach(this); if (attachSuccess) { binding.setLinked(); } else { toLink.add(binding);
@Test public void testSingletonBindingDelegatesSetVisiting() { singletonBinding.setVisiting(true); assertThat(wrappedBinding.isVisiting()).isTrue(); }
@Test public void testSingletonBindingDelegatesSetCycleFree() { singletonBinding.setCycleFree(true); assertThat(wrappedBinding.isCycleFree()).isTrue(); }
@Override public void getDependencies(Set<Binding<?>> get, Set<Binding<?>> injectMembers) { binding.getDependencies(get, injectMembers); }
@Override public boolean isLinked() { return binding.isLinked(); }
/** * Returns a scoped binding for {@code binding}. */ static <T> Binding<T> scope(final Binding<T> binding) { if (!binding.isSingleton() || binding instanceof SingletonBinding) { return binding; // Default scoped binding or already a scoped binding. } return new SingletonBinding<T>(binding); }
@Referable class Node { public int id; public Node[] reference; public Node(int id, Node...reference) { this.id = id; this.reference = reference; } } public static void main(String[] args) throws Exception { Node a = new Node(0); Node b = new Node(1); Node c = new Node(2); a.reference = new Node[] {b, c}; b.reference = new Node[] {a}; c.reference = new Node[] {c}; Binding binding = Bindings.getBinding( Node.class ); Serializer s = binding.serializer(); byte[] data = s.serialize(a); Node d = (Node) s.deserialize( data ); System.out.println( binding.toString(d) ); }
@Override public boolean isCycleFree() { return binding.isCycleFree(); }
@Override public boolean isVisiting() { return binding.isVisiting(); }
@Override protected void setLinked() { binding.setLinked(); }
@Override public void setCycleFree(final boolean cycleFree) { binding.setCycleFree(cycleFree); }
@Override public void setVisiting(final boolean visiting) { binding.setVisiting(visiting); }
@Test public void testSingletonBindingDelegatesIsVisiting() { wrappedBinding.setVisiting(true); assertThat(singletonBinding.isVisiting()).isTrue(); }