package ilarkesto.core.scope; import ilarkesto.core.event.AEventBus; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class CascadingScope extends Scope { int id; Scope parentScope; String name; Map<Integer, CascadingScope> childScopesById = new LinkedHashMap<Integer, CascadingScope>(); ComponentReflector componentReflector; Map<String, Object> componentsByName = new HashMap<String, Object>(); private boolean wiringRequired = true; CascadingScope(Scope parentScope, String name, ComponentReflector componentReflector) { this.id = ID_GENERATOR.nextId(); this.parentScope = parentScope; assert name != null; this.name = name; this.componentReflector = componentReflector; putComponent(AEventBus.DEFAULT_COMPONENT_NAME, new CascadingScopeEventBus(this)); } public synchronized void wireComponents() { log.info("Wiring components:", getName()); wiringRequired = false; List components = new ArrayList(componentsByName.values()); for (Object component : components) { componentReflector.injectComponents(component, this); } for (Object component : components) { componentReflector.callInitializationMethods(component); componentReflector.outjectComponents(component, this); } if (wiringRequired) wireComponents(); } @Override public Object getComponent(String name) { if (wiringRequired) wireComponents(); Object component = componentsByName.get(name); if (component == null) return getComponentFromParentScope(name); return component; } private Object getComponentFromParentScope(String name) { if (parentScope == null) return null; return parentScope.getComponent(name); } @Override public synchronized <T> T putComponent(String name, T component) { assert name != null; assert component != null; Object existingComponent = componentsByName.get(name); if (existingComponent == component) return component; log.info("Putting component:", name); componentsByName.put(name, component); wiringRequired = true; return component; } @Override public List getAllComponents() { List ret = new ArrayList(); if (parentScope != null) ret.addAll(parentScope.getAllComponents()); ret.addAll(getLocalComponents()); return ret; } public CascadingScope createScope(String name) { log.info("Creating sub scope:", getName(), "->", name); CascadingScope scope = new CascadingScope(this, name, componentReflector); childScopesById.put(scope.getId(), scope); return scope; } public List getLocalComponents() { if (wiringRequired) wireComponents(); List ret = new ArrayList(); ret.addAll(componentsByName.values()); return ret; } @Override public String getName() { return parentScope == null ? name : parentScope.getName() + ">" + name; } public int getId() { return id; } @Override public String toString() { return id + ":" + super.toString(); } public static CascadingScope get() { return (CascadingScope) Scope.get(); } static final IdGenerator ID_GENERATOR = new IdGenerator(); static class IdGenerator { int lastId = -1; int nextId() { synchronized (ID_GENERATOR) { return ++lastId; } } }; }