/**
 * <copyright>
 * </copyright>
 *
 * $Id: ProcessImpl.java,v 1.3 2006/09/07 00:05:59 klow Exp $
 */
package org.eclipse.epf.xml.uma.impl;

import java.util.Collection;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EDataTypeEList;
import org.eclipse.epf.xml.uma.UmaPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Process</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.epf.xml.uma.impl.ProcessImpl#getIncludesPattern <em>Includes Pattern</em>}</li>
 *   <li>{@link org.eclipse.epf.xml.uma.impl.ProcessImpl#getDefaultContext <em>Default Context</em>}</li>
 *   <li>{@link org.eclipse.epf.xml.uma.impl.ProcessImpl#getValidContext <em>Valid Context</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class ProcessImpl extends ActivityImpl implements org.eclipse.epf.xml.uma.Process {
	/**
	 * The cached value of the '{@link #getIncludesPattern() <em>Includes Pattern</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIncludesPattern()
	 * @generated
	 * @ordered
	 */
	protected EList includesPattern = null;

	/**
	 * The default value of the '{@link #getDefaultContext() <em>Default Context</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultContext()
	 * @generated
	 * @ordered
	 */
	protected static final String DEFAULT_CONTEXT_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getDefaultContext() <em>Default Context</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultContext()
	 * @generated
	 * @ordered
	 */
	protected String defaultContext = DEFAULT_CONTEXT_EDEFAULT;

	/**
	 * The cached value of the '{@link #getValidContext() <em>Valid Context</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getValidContext()
	 * @generated
	 * @ordered
	 */
	protected EList validContext = null;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected ProcessImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected EClass eStaticClass() {
		return UmaPackage.Literals.PROCESS;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getIncludesPattern() {
		if (includesPattern == null) {
			includesPattern = new EDataTypeEList(String.class, this, UmaPackage.PROCESS__INCLUDES_PATTERN);
		}
		return includesPattern;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getDefaultContext() {
		return defaultContext;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDefaultContext(String newDefaultContext) {
		String oldDefaultContext = defaultContext;
		defaultContext = newDefaultContext;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UmaPackage.PROCESS__DEFAULT_CONTEXT, oldDefaultContext, defaultContext));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getValidContext() {
		if (validContext == null) {
			validContext = new EDataTypeEList(String.class, this, UmaPackage.PROCESS__VALID_CONTEXT);
		}
		return validContext;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case UmaPackage.PROCESS__INCLUDES_PATTERN:
				return getIncludesPattern();
			case UmaPackage.PROCESS__DEFAULT_CONTEXT:
				return getDefaultContext();
			case UmaPackage.PROCESS__VALID_CONTEXT:
				return getValidContext();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case UmaPackage.PROCESS__INCLUDES_PATTERN:
				getIncludesPattern().clear();
				getIncludesPattern().addAll((Collection)newValue);
				return;
			case UmaPackage.PROCESS__DEFAULT_CONTEXT:
				setDefaultContext((String)newValue);
				return;
			case UmaPackage.PROCESS__VALID_CONTEXT:
				getValidContext().clear();
				getValidContext().addAll((Collection)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eUnset(int featureID) {
		switch (featureID) {
			case UmaPackage.PROCESS__INCLUDES_PATTERN:
				getIncludesPattern().clear();
				return;
			case UmaPackage.PROCESS__DEFAULT_CONTEXT:
				setDefaultContext(DEFAULT_CONTEXT_EDEFAULT);
				return;
			case UmaPackage.PROCESS__VALID_CONTEXT:
				getValidContext().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case UmaPackage.PROCESS__INCLUDES_PATTERN:
				return includesPattern != null && !includesPattern.isEmpty();
			case UmaPackage.PROCESS__DEFAULT_CONTEXT:
				return DEFAULT_CONTEXT_EDEFAULT == null ? defaultContext != null : !DEFAULT_CONTEXT_EDEFAULT.equals(defaultContext);
			case UmaPackage.PROCESS__VALID_CONTEXT:
				return validContext != null && !validContext.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (includesPattern: ");
		result.append(includesPattern);
		result.append(", defaultContext: ");
		result.append(defaultContext);
		result.append(", validContext: ");
		result.append(validContext);
		result.append(')');
		return result.toString();
	}

} //ProcessImpl