DmcAttribute<?> existing = null;
Iterator<Modifier> modifiers = mods.getMV();
while(modifiers.hasNext()){
Modifier mod = modifiers.next();
existing = get(mod.getAttributeName());
// HACK: have to rationalize the attrInfo thing
if (existing != null)
existing.getAttributeInfo();
switch(mod.getModifyType()){
case ADD:
if (existing == null){
Iterator<Object> it = (Iterator<Object>) mod.getAttribute().getMV();
Object value = it.next();
if (value instanceof DmcNamedObjectREF){
// we do things a little different for object refs because it relies on the lastValue
// to create the backref modifier
existing = mod.getAttribute().getNew();
DmcNamedObjectREF<?> ref = (DmcNamedObjectREF<?>)value;
Object lastValue = existing.add(ref);
setLastValue(lastValue);
add(existing.getAttributeInfo(),existing);
}
else{
// NOTE: we add a clone of the attribute since, if we don't, we wind
// up storing the attribute instance that's in the modifier and adding
// stuff to it!
add(mod.getAttributeName(), mod.getAttribute().cloneIt());
}
anyChange = true;
}
else{
Iterator<Object> it = (Iterator<Object>) mod.getAttribute().getMV();
Object value = it.next();
// NOTE: there will only ever be one value in the attribute and we have
// to use an Iterator to get the value out.
if ((value instanceof DmcNamedObjectREF) && !(value instanceof DmcExtendedReferenceIF)){
// If the attribute is an object reference, we have to determine
// whether we have the object or just its name - and perform the
// add() accordingly.
DmcNamedObjectREF<?> ref = (DmcNamedObjectREF<?>)value;
Object lastValue = existing.add(ref);
if (lastValue != null){
setLastValue(lastValue);
anyChange = true;
add(existing.getAttributeInfo(),existing);
}
}
else{
if ( existing.add(value) != null)
anyChange = true;
}
}
break;
case DEL:
if (existing == null){
// The attribute being modified doesn't exist
// TODO what to do with the deletion of a value from a non-existent attribute???
}
else{
// NOTE: there will only ever be one value in the attribute and we have
// to use an Iterator to get the value out.
Iterator<Object> it = (Iterator<Object>) mod.getAttribute().getMV();
Object value = it.next();
if ( (value instanceof DmcNamedObjectREF) && !(value instanceof DmcExtendedReferenceIF)){
// If the attribute is an object reference, we have to determine
// whether we have the object or just its name - and perform the
// del() accordingly.
DmcNamedObjectREF<?> ref = (DmcNamedObjectREF<?>)value;
setLastValue(ref);
anyChange = true;
del(existing.getAttributeInfo(), value);
}
else{
if (value instanceof DmcMappedAttributeIF){
if (existing.del(((DmcMappedAttributeIF)value).getKey()) != null)
anyChange = true;
}
else if ( existing.del(value) != null){
anyChange = true;
}
}
if (existing.getMVSize() == 0){
rem(existing.getAttributeInfo());
}
}
break;
case SET:
if (existing == null){
set(mod.getAttributeName(),mod.getAttribute());
anyChange = true;
}
else{
Object value = mod.getAttribute().getSV();
if (value instanceof DmcNamedObjectREF){
// We had a value in this attribute to start with, so clean
// up the back reference before we apply the new value
((DmcTypeNamedObjectREF<?, ?>)existing).removeBackReferences();
DmcNamedObjectREF<?> ref = (DmcNamedObjectREF<?>)value;
if (existing.set(ref) != null){
set(existing.getAttributeInfo(),existing);
anyChange = true;
}
}
else{
if (existing.set(mod.getAttribute().getSV()) != null)
anyChange = true;
}
}
break;
case NTH:
// When a value is nulled, the modifier just contains the attribute info, not
// a value holding attribute.
int index = mod.getIndex();
Object value = null;
if (mod.getAttribute() != null)
value = mod.getAttribute().getMVnth(index);
if (existing == null){
// NOTE: we add a clone of the attribute since, if we don't, we wind
// up storing the attribute instance that's in the modifier and adding
// stuff to it!
if (value != null){
setLastValue(value);
nth(mod.getAttribute().getAttributeInfo(),index,mod.getAttribute().cloneIt(),null);
anyChange = true;
}
}
else{
Object previous = existing.getMVnth(index);
if (value == null){
// We're removing the value at the current slot
// We currently have a value and we're nulling it so there's been a change
if (previous != null){
existing.setMVnth(index, value);
setLastValue(value);
nth(existing.getAttributeInfo(), index, existing, previous);
anyChange = true;
}
}
else{
// if ((value instanceof DmcNamedObjectREF) && !(value instanceof DmcExtendedReferenceIF)){
if (value instanceof DmcNamedObjectREF){
// If the attribute is an object reference, we have to determine
// whether we have the object or just its name - and perform the
// add() accordingly.
DmcNamedObjectREF<?> ref = (DmcNamedObjectREF<?>)value;
if (existing.setMVnth(index, ref) != null){
setLastValue(ref);
nth(existing.getAttributeInfo(), index, existing, previous);
anyChange = true;
}
}
else{
if ( existing.setMVnth(index,value) != null)
anyChange = true;
}
}
if (!existing.hasValue()){
rem(existing.getAttributeInfo());
}
}
break;
case REM:
if (rem(mod.getAttributeName()) != null)
anyChange = true;
break;
}
}