/**
 * Copyright (c) 2010 Mia-Software.
 *    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:
 *    
 *    	   Nicolas Guyomar (Mia-Software) - initial API and implementation
 */
package org.eclipse.modisco.jee.ejbjar.EjbJar30.impl;

import java.lang.String;

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.impl.EObjectImpl;

import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.modisco.jee.ejbjar.EjbJar30.DescriptionType;
import org.eclipse.modisco.jee.ejbjar.EjbJar30.EjbJar30Package;
import org.eclipse.modisco.jee.ejbjar.EjbJar30.EmptyType;
import org.eclipse.modisco.jee.ejbjar.EjbJar30.MethodPermissionType;
import org.eclipse.modisco.jee.ejbjar.EjbJar30.MethodType;
import org.eclipse.modisco.jee.ejbjar.EjbJar30.RoleNameType;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Method Permission Type</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.modisco.jee.ejbjar.EjbJar30.impl.MethodPermissionTypeImpl#getDescription <em>Description</em>}</li>
 *   <li>{@link org.eclipse.modisco.jee.ejbjar.EjbJar30.impl.MethodPermissionTypeImpl#getRoleName <em>Role Name</em>}</li>
 *   <li>{@link org.eclipse.modisco.jee.ejbjar.EjbJar30.impl.MethodPermissionTypeImpl#getUnchecked <em>Unchecked</em>}</li>
 *   <li>{@link org.eclipse.modisco.jee.ejbjar.EjbJar30.impl.MethodPermissionTypeImpl#getMethod <em>Method</em>}</li>
 *   <li>{@link org.eclipse.modisco.jee.ejbjar.EjbJar30.impl.MethodPermissionTypeImpl#getId <em>Id</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class MethodPermissionTypeImpl extends EObjectImpl implements MethodPermissionType {
	/**
	 * The cached value of the '{@link #getDescription() <em>Description</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDescription()
	 * @generated
	 * @ordered
	 */
	protected EList<DescriptionType> description;

	/**
	 * The cached value of the '{@link #getRoleName() <em>Role Name</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRoleName()
	 * @generated
	 * @ordered
	 */
	protected EList<RoleNameType> roleName;

	/**
	 * The cached value of the '{@link #getUnchecked() <em>Unchecked</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getUnchecked()
	 * @generated
	 * @ordered
	 */
	protected EmptyType unchecked;

	/**
	 * The cached value of the '{@link #getMethod() <em>Method</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMethod()
	 * @generated
	 * @ordered
	 */
	protected EList<MethodType> method;

	/**
	 * The default value of the '{@link #getId() <em>Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected static final String ID_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getId() <em>Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected String id = ID_EDEFAULT;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected MethodPermissionTypeImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return EjbJar30Package.eINSTANCE.getMethodPermissionType();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<DescriptionType> getDescription() {
		if (description == null) {
			description = new EObjectContainmentEList<DescriptionType>(DescriptionType.class, this, EjbJar30Package.METHOD_PERMISSION_TYPE__DESCRIPTION);
		}
		return description;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<RoleNameType> getRoleName() {
		if (roleName == null) {
			roleName = new EObjectContainmentEList<RoleNameType>(RoleNameType.class, this, EjbJar30Package.METHOD_PERMISSION_TYPE__ROLE_NAME);
		}
		return roleName;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EmptyType getUnchecked() {
		return unchecked;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetUnchecked(EmptyType newUnchecked, NotificationChain msgs) {
		EmptyType oldUnchecked = unchecked;
		unchecked = newUnchecked;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED, oldUnchecked, newUnchecked);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setUnchecked(EmptyType newUnchecked) {
		if (newUnchecked != unchecked) {
			NotificationChain msgs = null;
			if (unchecked != null)
				msgs = ((InternalEObject)unchecked).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED, null, msgs);
			if (newUnchecked != null)
				msgs = ((InternalEObject)newUnchecked).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED, null, msgs);
			msgs = basicSetUnchecked(newUnchecked, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED, newUnchecked, newUnchecked));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<MethodType> getMethod() {
		if (method == null) {
			method = new EObjectContainmentEList<MethodType>(MethodType.class, this, EjbJar30Package.METHOD_PERMISSION_TYPE__METHOD);
		}
		return method;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getId() {
		return id;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setId(String newId) {
		String oldId = id;
		id = newId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EjbJar30Package.METHOD_PERMISSION_TYPE__ID, oldId, id));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case EjbJar30Package.METHOD_PERMISSION_TYPE__DESCRIPTION:
				return ((InternalEList<?>)getDescription()).basicRemove(otherEnd, msgs);
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ROLE_NAME:
				return ((InternalEList<?>)getRoleName()).basicRemove(otherEnd, msgs);
			case EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED:
				return basicSetUnchecked(null, msgs);
			case EjbJar30Package.METHOD_PERMISSION_TYPE__METHOD:
				return ((InternalEList<?>)getMethod()).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 EjbJar30Package.METHOD_PERMISSION_TYPE__DESCRIPTION:
				return getDescription();
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ROLE_NAME:
				return getRoleName();
			case EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED:
				return getUnchecked();
			case EjbJar30Package.METHOD_PERMISSION_TYPE__METHOD:
				return getMethod();
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ID:
				return getId();
		}
		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 EjbJar30Package.METHOD_PERMISSION_TYPE__DESCRIPTION:
				getDescription().clear();
				getDescription().addAll((Collection<? extends DescriptionType>)newValue);
				return;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ROLE_NAME:
				getRoleName().clear();
				getRoleName().addAll((Collection<? extends RoleNameType>)newValue);
				return;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED:
				setUnchecked((EmptyType)newValue);
				return;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__METHOD:
				getMethod().clear();
				getMethod().addAll((Collection<? extends MethodType>)newValue);
				return;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ID:
				setId((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case EjbJar30Package.METHOD_PERMISSION_TYPE__DESCRIPTION:
				getDescription().clear();
				return;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ROLE_NAME:
				getRoleName().clear();
				return;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED:
				setUnchecked((EmptyType)null);
				return;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__METHOD:
				getMethod().clear();
				return;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ID:
				setId(ID_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case EjbJar30Package.METHOD_PERMISSION_TYPE__DESCRIPTION:
				return description != null && !description.isEmpty();
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ROLE_NAME:
				return roleName != null && !roleName.isEmpty();
			case EjbJar30Package.METHOD_PERMISSION_TYPE__UNCHECKED:
				return unchecked != null;
			case EjbJar30Package.METHOD_PERMISSION_TYPE__METHOD:
				return method != null && !method.isEmpty();
			case EjbJar30Package.METHOD_PERMISSION_TYPE__ID:
				return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
		}
		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(" (id: "); //$NON-NLS-1$
		result.append(id);
		result.append(')');
		return result.toString();
	}

} //MethodPermissionTypeImpl
