/**
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *  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
 *  
 *  Contributors:                                                      
 *     Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 *  
 *  generated from AuthoritarionDSL.xcore
 * 
 *  
 */
package org.eclipse.osbp.xtext.authorizationdsl.impl;

import java.util.Collection;

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

import org.eclipse.emf.common.util.EList;

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

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

import org.eclipse.emf.ecore.util.EDataTypeEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.osbp.dsl.semantic.entity.LBean;

import org.eclipse.osbp.xtext.authorizationdsl.AuthorizationDSLPackage;
import org.eclipse.osbp.xtext.authorizationdsl.RoleBean;
import org.eclipse.osbp.xtext.authorizationdsl.RoleBeanFeature;
import org.eclipse.osbp.xtext.authorizationdsl.RoleEnum;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Role Bean</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.authorizationdsl.impl.RoleBeanImpl#getBeanAuthorized <em>Bean Authorized</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.authorizationdsl.impl.RoleBeanImpl#getBeanFeatures <em>Bean Features</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.authorizationdsl.impl.RoleBeanImpl#getBeanRef <em>Bean Ref</em>}</li>
 * </ul>
 *
 * @generated
 */
public class RoleBeanImpl extends RoleElementImpl implements RoleBean {
	/**
	 * The cached value of the '{@link #getBeanAuthorized() <em>Bean Authorized</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBeanAuthorized()
	 * @generated
	 * @ordered
	 */
	protected EList<RoleEnum> beanAuthorized;

	/**
	 * The cached value of the '{@link #getBeanFeatures() <em>Bean Features</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBeanFeatures()
	 * @generated
	 * @ordered
	 */
	protected EList<RoleBeanFeature> beanFeatures;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<RoleEnum> getBeanAuthorized() {
		if (beanAuthorized == null) {
			beanAuthorized = new EDataTypeEList<RoleEnum>(RoleEnum.class, this, AuthorizationDSLPackage.ROLE_BEAN__BEAN_AUTHORIZED);
		}
		return beanAuthorized;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<RoleBeanFeature> getBeanFeatures() {
		if (beanFeatures == null) {
			beanFeatures = new EObjectContainmentEList<RoleBeanFeature>(RoleBeanFeature.class, this, AuthorizationDSLPackage.ROLE_BEAN__BEAN_FEATURES);
		}
		return beanFeatures;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LBean getBeanRef() {
		if (beanRef != null && beanRef.eIsProxy()) {
			InternalEObject oldBeanRef = (InternalEObject)beanRef;
			beanRef = (LBean)eResolveProxy(oldBeanRef);
			if (beanRef != oldBeanRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, AuthorizationDSLPackage.ROLE_BEAN__BEAN_REF, oldBeanRef, beanRef));
			}
		}
		return beanRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LBean basicGetBeanRef() {
		return beanRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBeanRef(LBean newBeanRef) {
		LBean oldBeanRef = beanRef;
		beanRef = newBeanRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AuthorizationDSLPackage.ROLE_BEAN__BEAN_REF, oldBeanRef, beanRef));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_FEATURES:
				return ((InternalEList<?>)getBeanFeatures()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_AUTHORIZED:
				return getBeanAuthorized();
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_FEATURES:
				return getBeanFeatures();
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_REF:
				if (resolve) return getBeanRef();
				return basicGetBeanRef();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_AUTHORIZED:
				getBeanAuthorized().clear();
				getBeanAuthorized().addAll((Collection<? extends RoleEnum>)newValue);
				return;
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_FEATURES:
				getBeanFeatures().clear();
				getBeanFeatures().addAll((Collection<? extends RoleBeanFeature>)newValue);
				return;
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_REF:
				setBeanRef((LBean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_AUTHORIZED:
				getBeanAuthorized().clear();
				return;
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_FEATURES:
				getBeanFeatures().clear();
				return;
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_REF:
				setBeanRef((LBean)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_AUTHORIZED:
				return beanAuthorized != null && !beanAuthorized.isEmpty();
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_FEATURES:
				return beanFeatures != null && !beanFeatures.isEmpty();
			case AuthorizationDSLPackage.ROLE_BEAN__BEAN_REF:
				return beanRef != null;
		}
		return super.eIsSet(featureID);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (beanAuthorized: ");
		result.append(beanAuthorized);
		result.append(')');
		return result.toString();
	}

} //RoleBeanImpl
