/*******************************************************************************
 * Copyright (c) 2007 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 API and implementation
 *******************************************************************************/
package org.eclipse.jst.javaee.web.internal.impl;

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

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.jst.javaee.web.FormLoginConfig;
import org.eclipse.jst.javaee.web.LoginConfig;

import org.eclipse.jst.javaee.web.internal.metadata.WebPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Login Config</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.jst.javaee.web.internal.impl.LoginConfigImpl#getAuthMethod <em>Auth Method</em>}</li>
 *   <li>{@link org.eclipse.jst.javaee.web.internal.impl.LoginConfigImpl#getRealmName <em>Realm Name</em>}</li>
 *   <li>{@link org.eclipse.jst.javaee.web.internal.impl.LoginConfigImpl#getFormLoginConfig <em>Form Login Config</em>}</li>
 *   <li>{@link org.eclipse.jst.javaee.web.internal.impl.LoginConfigImpl#getId <em>Id</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class LoginConfigImpl extends EObjectImpl implements LoginConfig {
	/**
	 * The default value of the '{@link #getAuthMethod() <em>Auth Method</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAuthMethod()
	 * @generated
	 * @ordered
	 */
	protected static final String AUTH_METHOD_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getAuthMethod() <em>Auth Method</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAuthMethod()
	 * @generated
	 * @ordered
	 */
	protected String authMethod = AUTH_METHOD_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getRealmName() <em>Realm Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRealmName()
	 * @generated
	 * @ordered
	 */
	protected String realmName = REALM_NAME_EDEFAULT;

	/**
	 * The cached value of the '{@link #getFormLoginConfig() <em>Form Login Config</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFormLoginConfig()
	 * @generated
	 * @ordered
	 */
	protected FormLoginConfig formLoginConfig = null;

	/**
	 * 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 LoginConfigImpl() {
		super();
	}

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAuthMethod(String newAuthMethod) {
		String oldAuthMethod = authMethod;
		authMethod = newAuthMethod;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, WebPackage.LOGIN_CONFIG__AUTH_METHOD, oldAuthMethod, authMethod));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRealmName(String newRealmName) {
		String oldRealmName = realmName;
		realmName = newRealmName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, WebPackage.LOGIN_CONFIG__REALM_NAME, oldRealmName, realmName));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FormLoginConfig getFormLoginConfig() {
		return formLoginConfig;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetFormLoginConfig(FormLoginConfig newFormLoginConfig, NotificationChain msgs) {
		FormLoginConfig oldFormLoginConfig = formLoginConfig;
		formLoginConfig = newFormLoginConfig;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG, oldFormLoginConfig, newFormLoginConfig);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setFormLoginConfig(FormLoginConfig newFormLoginConfig) {
		if (newFormLoginConfig != formLoginConfig) {
			NotificationChain msgs = null;
			if (formLoginConfig != null)
				msgs = ((InternalEObject)formLoginConfig).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG, null, msgs);
			if (newFormLoginConfig != null)
				msgs = ((InternalEObject)newFormLoginConfig).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG, null, msgs);
			msgs = basicSetFormLoginConfig(newFormLoginConfig, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG, newFormLoginConfig, newFormLoginConfig));
	}

	/**
	 * <!-- 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, WebPackage.LOGIN_CONFIG__ID, oldId, id));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG:
				return basicSetFormLoginConfig(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case WebPackage.LOGIN_CONFIG__AUTH_METHOD:
				return getAuthMethod();
			case WebPackage.LOGIN_CONFIG__REALM_NAME:
				return getRealmName();
			case WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG:
				return getFormLoginConfig();
			case WebPackage.LOGIN_CONFIG__ID:
				return getId();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case WebPackage.LOGIN_CONFIG__AUTH_METHOD:
				setAuthMethod((String)newValue);
				return;
			case WebPackage.LOGIN_CONFIG__REALM_NAME:
				setRealmName((String)newValue);
				return;
			case WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG:
				setFormLoginConfig((FormLoginConfig)newValue);
				return;
			case WebPackage.LOGIN_CONFIG__ID:
				setId((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eUnset(int featureID) {
		switch (featureID) {
			case WebPackage.LOGIN_CONFIG__AUTH_METHOD:
				setAuthMethod(AUTH_METHOD_EDEFAULT);
				return;
			case WebPackage.LOGIN_CONFIG__REALM_NAME:
				setRealmName(REALM_NAME_EDEFAULT);
				return;
			case WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG:
				setFormLoginConfig((FormLoginConfig)null);
				return;
			case WebPackage.LOGIN_CONFIG__ID:
				setId(ID_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case WebPackage.LOGIN_CONFIG__AUTH_METHOD:
				return AUTH_METHOD_EDEFAULT == null ? authMethod != null : !AUTH_METHOD_EDEFAULT.equals(authMethod);
			case WebPackage.LOGIN_CONFIG__REALM_NAME:
				return REALM_NAME_EDEFAULT == null ? realmName != null : !REALM_NAME_EDEFAULT.equals(realmName);
			case WebPackage.LOGIN_CONFIG__FORM_LOGIN_CONFIG:
				return formLoginConfig != null;
			case WebPackage.LOGIN_CONFIG__ID:
				return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
		}
		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(" (authMethod: "); //$NON-NLS-1$
		result.append(authMethod);
		result.append(", realmName: "); //$NON-NLS-1$
		result.append(realmName);
		result.append(", id: "); //$NON-NLS-1$
		result.append(id);
		result.append(')');
		return result.toString();
	}

} //LoginConfigImpl