package org.sef4j.core.util.factorydef;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* a temporary context used at creation time, to keep track of dependency refs created
*/
public class DependencyObjectCreationContext {
private ObjectByDefRepositories repositories;
private List<String> currDisplayPathName = new ArrayList<String>();
private List<SharedRef<?>> dependencyRefs;
// ------------------------------------------------------------------------
public DependencyObjectCreationContext(ObjectByDefRepositories repositories, List<SharedRef<?>> dependencyRefs, String displayRootObjectName) {
this.repositories = repositories;
this.dependencyRefs = dependencyRefs;
currDisplayPathName.add(displayRootObjectName);
}
// ------------------------------------------------------------------------
public <TDef,T> T getOrCreateDependencyByDef(String dependencyDisplayName, TDef def, Object key) {
try (InnerCloseable toPop = withPushDependencyDisplayName(dependencyDisplayName)) {
SharedRef<T> tmpres = repositories.getOrCreateByDef(def, key);
addDependencyRef(tmpres);
return tmpres.getObject();
}
}
/** helper for <code>getOrCreateDependencyByDef(,,null)</code> */
public <TDef,T> T getOrCreateDependencyByDef(String dependencyDisplayName, TDef def) {
return getOrCreateDependencyByDef(dependencyDisplayName, def, null);
}
public <TDef,T> List<T> getOrCreateDependencyByDefs(String dependencyDisplayName, Collection<TDef> defs) {
try (InnerCloseable toPop = withPushDependencyDisplayName(dependencyDisplayName)) {
List<T> res = new ArrayList<T>(defs.size());
List<SharedRef<T>> tmpres = repositories.getOrCreateByDefs(defs);
for(SharedRef<T> depRef : tmpres) {
addDependencyRef(depRef);
res.add(depRef.getObject());
}
return res;
}
}
public void addDependencyRef(SharedRef<?> ref) {
dependencyRefs.add(ref);
}
public String getCurrObjectDisplayName() {
return String.join(".", currDisplayPathName);
}
public InnerCloseable withPushDependencyDisplayName(String name) {
currDisplayPathName.add(name);
return new InnerCloseable();
}
/** internal helper, for <code>pus() try { ..} finally { pop() }</code> */
protected class InnerCloseable implements Closeable {
public void close() {
currDisplayPathName.remove(currDisplayPathName.size() - 1);
}
}
}