/**
 * Copyright (c) 2014, Loetz GmbH&Co.KG (Heidelberg)
 *  All rights reserved. This program and the accompanying materials 
 *  are made available under the terms of the Eclipse Public License 2.0  
 *  which accompanies this distribution, and is available at 
 *  https://www.eclipse.org/legal/epl-2.0/ 
 *  
 *  SPDX-License-Identifier: EPL-2.0 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Joerg Riegel - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.datainterchange.impl;

import org.eclipse.emf.common.notify.Notification;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;

import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference;

import org.eclipse.osbp.xtext.datainterchange.DataDSLPackage;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeJoinAttr;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Data Interchange Join Attr</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeJoinAttrImpl#getRef <em>Ref</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeJoinAttrImpl#getRefProperty <em>Ref Property</em>}</li>
 * </ul>
 *
 * @generated
 */
public class DataInterchangeJoinAttrImpl extends DataInterchangeLazyResolverImpl implements DataInterchangeJoinAttr {
	/**
	 * The cached value of the '{@link #getRef() <em>Ref</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRef()
	 * @generated
	 * @ordered
	 */
	protected LEntityReference ref;

	/**
	 * The cached value of the '{@link #getRefProperty() <em>Ref Property</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRefProperty()
	 * @generated
	 * @ordered
	 */
	protected LEntityAttribute refProperty;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityReference getRef() {
		if (ref != null && ref.eIsProxy()) {
			InternalEObject oldRef = (InternalEObject)ref;
			ref = (LEntityReference)eResolveProxy(oldRef);
			if (ref != oldRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF, oldRef, ref));
			}
		}
		return ref;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityReference basicGetRef() {
		return ref;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRef(LEntityReference newRef) {
		LEntityReference oldRef = ref;
		ref = newRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF, oldRef, ref));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute getRefProperty() {
		if (refProperty != null && refProperty.eIsProxy()) {
			InternalEObject oldRefProperty = (InternalEObject)refProperty;
			refProperty = (LEntityAttribute)eResolveProxy(oldRefProperty);
			if (refProperty != oldRefProperty) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF_PROPERTY, oldRefProperty, refProperty));
			}
		}
		return refProperty;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute basicGetRefProperty() {
		return refProperty;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRefProperty(LEntityAttribute newRefProperty) {
		LEntityAttribute oldRefProperty = refProperty;
		refProperty = newRefProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF_PROPERTY, oldRefProperty, refProperty));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF:
				if (resolve) return getRef();
				return basicGetRef();
			case DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF_PROPERTY:
				if (resolve) return getRefProperty();
				return basicGetRefProperty();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF:
				setRef((LEntityReference)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF_PROPERTY:
				setRefProperty((LEntityAttribute)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF:
				setRef((LEntityReference)null);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF_PROPERTY:
				setRefProperty((LEntityAttribute)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF:
				return ref != null;
			case DataDSLPackage.DATA_INTERCHANGE_JOIN_ATTR__REF_PROPERTY:
				return refProperty != null;
		}
		return super.eIsSet(featureID);
	}

} //DataInterchangeJoinAttrImpl
