net.sf.andromedaioc.model.builder.processor.ParentBeansContextModelProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of andromeda-ioc Show documentation
Show all versions of andromeda-ioc Show documentation
Inversion of Control Framework for Android
The newest version!
package net.sf.andromedaioc.model.builder.processor;
import net.sf.andromedaioc.exception.CircularInheritanceException;
import net.sf.andromedaioc.exception.ParentBeanNotFoundException;
import net.sf.andromedaioc.model.beans.BeanModel;
import net.sf.andromedaioc.model.beans.ContextModel;
import net.sf.andromedaioc.model.beans.ReferenceKey;
import java.util.*;
/**
* This processor merge parent and child beans properties overriding parent with
* child. Parent abstract beans will be removed after properties are merged
*
* @author Alexey Mitrov
*/
public class ParentBeansContextModelProcessor implements ContextModelProcessor {
public ContextModel process(ContextModel input) {
if(input.getBeans().size() <= 0) {
return input;
}
Map inputBeans = input.getBeans();
Map outputBeans = new HashMap();
for(Map.Entry entry : inputBeans.entrySet()) {
BeanModel model = entry.getValue();
if(!model.isAbstractBean()) {
if(model.getParent() != null) {
Collection parentalChain = getParentalChain(model, inputBeans);
BeanModel mergedWithParentsBeanModel = mergeWithParents(parentalChain, inputBeans);
outputBeans.put(entry.getKey(), mergedWithParentsBeanModel);
} else {
outputBeans.put(entry.getKey(), entry.getValue());
}
}
}
return new ContextModel(outputBeans);
}
private Collection getParentalChain(BeanModel lastChild, Map inputBeans) {
Set chain = new LinkedHashSet();
chain.add(lastChild.getKey());
BeanModel model = lastChild;
ReferenceKey parentReference;
while((parentReference = model.getParent()) != null) {
BeanModel parentModel = inputBeans.get(parentReference);
if(parentModel == null) {
throw new ParentBeanNotFoundException(String.format("Parent bean with id = %s not found", parentReference.getId()));
}
if(chain.contains(parentReference)) {
throw new CircularInheritanceException(String.format("Circular inheritance found in parental chain: %s", chain));
}
chain.add(parentReference);
model = parentModel;
}
List chainList = new ArrayList(chain);
Collections.reverse(chainList);
return chainList;
}
private BeanModel mergeWithParents(Collection parentalChain, Map inputBeans) {
BeanModel mergedModel = new BeanModel();
for(ReferenceKey key : parentalChain) {
mergedModel.override(inputBeans.get(key));
}
return mergedModel;
}
}