//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.configuration;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;

/**
 * realized feature value for a toMany opposite feature
 * 
 * @author Jinhua Xi
 * @since 1.0
 *
 */
public class ToManyOppositeFeatureValue extends ToManyFeatureValue {
	
	public ToManyOppositeFeatureValue(MethodElement element, OppositeFeature feature, ElementRealizer realizer) {
		super(element, null, feature, realizer);
	}

	

	
	public void add(VariabilityElement owner, Object value) {
		
		// work around for opposite feature value that still return a single value instead of a list
		if ( value instanceof MethodElement ) {
			ArrayList v = new ArrayList();
			v.add(value);
			value = v;
		}
		
		if ( !(value instanceof List) ) {	
			return;
		}
			
		for (Iterator it = ((List) value).iterator(); it.hasNext();) {
			MethodElement e = (MethodElement) it.next();

			// RATLC00384319 - Replace does not completely remove
			// outgoing associations
			// if the opposite feature value has replacer in the
			// configuration
			// it's outgoing associations (i.e., this element) will be
			// replaced by the replacing element
			// as a result, the opposite feature value should drop the
			// replaced element
			//
			// for example, R1 -> responsible for A1, R2 responsible for
			// A2
			// if R2 replaces R1, then R2 still responsible for A2
			// but A1 does not have a responsible role (not R2)
			// so for A1's responsible role opposite feature,
			// the value R1 should be dropped instead of realize to R2
			// Jinhua Xi, 10/27/2005
			boolean isValueReplaced = (e instanceof VariabilityElement)
					&& (ConfigurationHelper.getReplacer((VariabilityElement) e, realizer.getConfiguration()) != null);
			if (!isValueReplaced) {
				MethodElement ce = ConfigurationHelper.getCalculatedElement(e, realizer);

				// calculated element can be null if it can't show
				if (ce != null && !values.contains(ce)) {
					values.add(ce);
				}
			}
		}	
	}
	
}
