package iot.jcypher.domain.mapping; import iot.jcypher.domain.mapping.surrogate.InnerClassSurrogate; import java.util.HashSet; import java.util.Iterator; import java.util.Map; public class CompoundObjectMapping extends ObjectMapping { private CompoundObjectType compoundObjectType; private Map<Class<?>, ObjectMapping> typeMappings; private HashSet<FieldMapping> fieldsToAccept; public CompoundObjectMapping(CompoundObjectType compoundObjectType, Map<Class<?>, ObjectMapping> typeMappings, Object toAccept) { super(); this.compoundObjectType = compoundObjectType; this.typeMappings = typeMappings; if (toAccept != null) { Class<?> toAcc = toAccept.getClass(); if (toAccept instanceof InnerClassSurrogate) toAcc = ((InnerClassSurrogate)toAccept).getRealClass(); this.fieldsToAccept = new HashSet<FieldMapping>(); Iterator<FieldMapping> it = typeMappings.get(toAcc).fieldMappingsIterator(); while(it.hasNext()) { this.fieldsToAccept.add(it.next()); } } else this.fieldsToAccept = null; } @Override public Iterator<FieldMapping> fieldMappingsIterator() { return new FieldMappingIterator(); } @Override public boolean shouldPerformFieldMapping(FieldMapping fieldMapping) { return this.fieldsToAccept == null || this.fieldsToAccept.contains(fieldMapping); } @Override public FieldMapping getFieldMappingForField(String fieldName) { throw new RuntimeException("not suppported"); } /****************************************/ public class FieldMappingIterator implements Iterator<FieldMapping> { private HashSet<FieldMapping> fieldMappingsSet = new HashSet<FieldMapping>(); private Iterator<CompoundObjectType> typeIterator = compoundObjectType.typeIterator(); private Iterator<FieldMapping> currentTypeFieldIterator; private FieldMapping nextFieldMapping; @Override public boolean hasNext() { this.nextFieldMapping = null; if (this.currentTypeFieldIterator == null) switchToNextType(); if (this.currentTypeFieldIterator != null) { // else the end is reached while (this.currentTypeFieldIterator.hasNext()) { FieldMapping next = this.currentTypeFieldIterator.next(); if (this.fieldMappingsSet.add(next)) { // this fieldMapping was not returned until now this.nextFieldMapping = next; return true; } } // reached the end of the currentTypeFieldIterator // recursively continue with the next one this.currentTypeFieldIterator = null; return hasNext(); } return false; } @Override public FieldMapping next() { return this.nextFieldMapping; } @Override public void remove() { throw new RuntimeException("operation not supported"); } private void switchToNextType() { while (this.typeIterator.hasNext()) { CompoundObjectType cType = this.typeIterator.next(); Class<?> typ = cType.getType(); ObjectMapping om = typeMappings.get(typ); if (om != null) { // may be null if the type is a supertype or interface, which itself has never // been stored to the graph this.currentTypeFieldIterator = om.fieldMappingsIterator(); return; } } // we hav reached the end this.currentTypeFieldIterator = null; } } }