/**
 * 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:  
 *  		Loetz GmbH&Co.KG - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.blip.impl;

import org.eclipse.bpmn2.ServiceTask;

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.xtext.blip.BlipDSLPackage;
import org.eclipse.osbp.xtext.blip.BlipServiceTask;
import org.eclipse.osbp.xtext.blip.ServiceExecutionModeEnum;

import org.eclipse.osbp.xtext.functionlibrarydsl.FunctionLibraryFunction;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Blip Service Task</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipServiceTaskImpl#getTask <em>Task</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipServiceTaskImpl#getOnEntry <em>On Entry</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipServiceTaskImpl#getOnExit <em>On Exit</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipServiceTaskImpl#getExecutionMode <em>Execution Mode</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipServiceTaskImpl#getTimeoutInSecs <em>Timeout In Secs</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipServiceTaskImpl#getFunction <em>Function</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipServiceTaskImpl#getWebServiceInterface <em>Web Service Interface</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipServiceTaskImpl#getWebServiceOperation <em>Web Service Operation</em>}</li>
 * </ul>
 *
 * @generated
 */
public class BlipServiceTaskImpl extends BlipItemImpl implements BlipServiceTask {
	/**
	 * The cached value of the '{@link #getTask() <em>Task</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTask()
	 * @generated
	 * @ordered
	 */
	protected ServiceTask task;

	/**
	 * The cached value of the '{@link #getOnEntry() <em>On Entry</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getOnEntry()
	 * @generated
	 * @ordered
	 */
	protected FunctionLibraryFunction onEntry;

	/**
	 * The cached value of the '{@link #getOnExit() <em>On Exit</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getOnExit()
	 * @generated
	 * @ordered
	 */
	protected FunctionLibraryFunction onExit;

	/**
	 * The default value of the '{@link #getExecutionMode() <em>Execution Mode</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getExecutionMode()
	 * @generated
	 * @ordered
	 */
	protected static final ServiceExecutionModeEnum EXECUTION_MODE_EDEFAULT = ServiceExecutionModeEnum.SYNC;

	/**
	 * The cached value of the '{@link #getExecutionMode() <em>Execution Mode</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getExecutionMode()
	 * @generated
	 * @ordered
	 */
	protected ServiceExecutionModeEnum executionMode = EXECUTION_MODE_EDEFAULT;

	/**
	 * The default value of the '{@link #getTimeoutInSecs() <em>Timeout In Secs</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTimeoutInSecs()
	 * @generated
	 * @ordered
	 */
	protected static final int TIMEOUT_IN_SECS_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getTimeoutInSecs() <em>Timeout In Secs</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTimeoutInSecs()
	 * @generated
	 * @ordered
	 */
	protected int timeoutInSecs = TIMEOUT_IN_SECS_EDEFAULT;

	/**
	 * The cached value of the '{@link #getFunction() <em>Function</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFunction()
	 * @generated
	 * @ordered
	 */
	protected FunctionLibraryFunction function;

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

	/**
	 * The cached value of the '{@link #getWebServiceInterface() <em>Web Service Interface</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getWebServiceInterface()
	 * @generated
	 * @ordered
	 */
	protected String webServiceInterface = WEB_SERVICE_INTERFACE_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getWebServiceOperation() <em>Web Service Operation</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getWebServiceOperation()
	 * @generated
	 * @ordered
	 */
	protected String webServiceOperation = WEB_SERVICE_OPERATION_EDEFAULT;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ServiceTask getTask() {
		if (task != null && task.eIsProxy()) {
			InternalEObject oldTask = (InternalEObject)task;
			task = (ServiceTask)eResolveProxy(oldTask);
			if (task != oldTask) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BlipDSLPackage.BLIP_SERVICE_TASK__TASK, oldTask, task));
			}
		}
		return task;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ServiceTask basicGetTask() {
		return task;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTask(ServiceTask newTask) {
		ServiceTask oldTask = task;
		task = newTask;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_SERVICE_TASK__TASK, oldTask, task));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction getOnEntry() {
		if (onEntry != null && onEntry.eIsProxy()) {
			InternalEObject oldOnEntry = (InternalEObject)onEntry;
			onEntry = (FunctionLibraryFunction)eResolveProxy(oldOnEntry);
			if (onEntry != oldOnEntry) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BlipDSLPackage.BLIP_SERVICE_TASK__ON_ENTRY, oldOnEntry, onEntry));
			}
		}
		return onEntry;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction basicGetOnEntry() {
		return onEntry;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setOnEntry(FunctionLibraryFunction newOnEntry) {
		FunctionLibraryFunction oldOnEntry = onEntry;
		onEntry = newOnEntry;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_SERVICE_TASK__ON_ENTRY, oldOnEntry, onEntry));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction getOnExit() {
		if (onExit != null && onExit.eIsProxy()) {
			InternalEObject oldOnExit = (InternalEObject)onExit;
			onExit = (FunctionLibraryFunction)eResolveProxy(oldOnExit);
			if (onExit != oldOnExit) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BlipDSLPackage.BLIP_SERVICE_TASK__ON_EXIT, oldOnExit, onExit));
			}
		}
		return onExit;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction basicGetOnExit() {
		return onExit;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setOnExit(FunctionLibraryFunction newOnExit) {
		FunctionLibraryFunction oldOnExit = onExit;
		onExit = newOnExit;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_SERVICE_TASK__ON_EXIT, oldOnExit, onExit));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ServiceExecutionModeEnum getExecutionMode() {
		return executionMode;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setExecutionMode(ServiceExecutionModeEnum newExecutionMode) {
		ServiceExecutionModeEnum oldExecutionMode = executionMode;
		executionMode = newExecutionMode == null ? EXECUTION_MODE_EDEFAULT : newExecutionMode;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_SERVICE_TASK__EXECUTION_MODE, oldExecutionMode, executionMode));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public int getTimeoutInSecs() {
		return timeoutInSecs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTimeoutInSecs(int newTimeoutInSecs) {
		int oldTimeoutInSecs = timeoutInSecs;
		timeoutInSecs = newTimeoutInSecs;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_SERVICE_TASK__TIMEOUT_IN_SECS, oldTimeoutInSecs, timeoutInSecs));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction getFunction() {
		if (function != null && function.eIsProxy()) {
			InternalEObject oldFunction = (InternalEObject)function;
			function = (FunctionLibraryFunction)eResolveProxy(oldFunction);
			if (function != oldFunction) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BlipDSLPackage.BLIP_SERVICE_TASK__FUNCTION, oldFunction, function));
			}
		}
		return function;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction basicGetFunction() {
		return function;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setFunction(FunctionLibraryFunction newFunction) {
		FunctionLibraryFunction oldFunction = function;
		function = newFunction;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_SERVICE_TASK__FUNCTION, oldFunction, function));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setWebServiceInterface(String newWebServiceInterface) {
		String oldWebServiceInterface = webServiceInterface;
		webServiceInterface = newWebServiceInterface;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_INTERFACE, oldWebServiceInterface, webServiceInterface));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setWebServiceOperation(String newWebServiceOperation) {
		String oldWebServiceOperation = webServiceOperation;
		webServiceOperation = newWebServiceOperation;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_OPERATION, oldWebServiceOperation, webServiceOperation));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case BlipDSLPackage.BLIP_SERVICE_TASK__TASK:
				if (resolve) return getTask();
				return basicGetTask();
			case BlipDSLPackage.BLIP_SERVICE_TASK__ON_ENTRY:
				if (resolve) return getOnEntry();
				return basicGetOnEntry();
			case BlipDSLPackage.BLIP_SERVICE_TASK__ON_EXIT:
				if (resolve) return getOnExit();
				return basicGetOnExit();
			case BlipDSLPackage.BLIP_SERVICE_TASK__EXECUTION_MODE:
				return getExecutionMode();
			case BlipDSLPackage.BLIP_SERVICE_TASK__TIMEOUT_IN_SECS:
				return getTimeoutInSecs();
			case BlipDSLPackage.BLIP_SERVICE_TASK__FUNCTION:
				if (resolve) return getFunction();
				return basicGetFunction();
			case BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_INTERFACE:
				return getWebServiceInterface();
			case BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_OPERATION:
				return getWebServiceOperation();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case BlipDSLPackage.BLIP_SERVICE_TASK__TASK:
				setTask((ServiceTask)newValue);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__ON_ENTRY:
				setOnEntry((FunctionLibraryFunction)newValue);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__ON_EXIT:
				setOnExit((FunctionLibraryFunction)newValue);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__EXECUTION_MODE:
				setExecutionMode((ServiceExecutionModeEnum)newValue);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__TIMEOUT_IN_SECS:
				setTimeoutInSecs((Integer)newValue);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__FUNCTION:
				setFunction((FunctionLibraryFunction)newValue);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_INTERFACE:
				setWebServiceInterface((String)newValue);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_OPERATION:
				setWebServiceOperation((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case BlipDSLPackage.BLIP_SERVICE_TASK__TASK:
				setTask((ServiceTask)null);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__ON_ENTRY:
				setOnEntry((FunctionLibraryFunction)null);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__ON_EXIT:
				setOnExit((FunctionLibraryFunction)null);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__EXECUTION_MODE:
				setExecutionMode(EXECUTION_MODE_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__TIMEOUT_IN_SECS:
				setTimeoutInSecs(TIMEOUT_IN_SECS_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__FUNCTION:
				setFunction((FunctionLibraryFunction)null);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_INTERFACE:
				setWebServiceInterface(WEB_SERVICE_INTERFACE_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_OPERATION:
				setWebServiceOperation(WEB_SERVICE_OPERATION_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case BlipDSLPackage.BLIP_SERVICE_TASK__TASK:
				return task != null;
			case BlipDSLPackage.BLIP_SERVICE_TASK__ON_ENTRY:
				return onEntry != null;
			case BlipDSLPackage.BLIP_SERVICE_TASK__ON_EXIT:
				return onExit != null;
			case BlipDSLPackage.BLIP_SERVICE_TASK__EXECUTION_MODE:
				return executionMode != EXECUTION_MODE_EDEFAULT;
			case BlipDSLPackage.BLIP_SERVICE_TASK__TIMEOUT_IN_SECS:
				return timeoutInSecs != TIMEOUT_IN_SECS_EDEFAULT;
			case BlipDSLPackage.BLIP_SERVICE_TASK__FUNCTION:
				return function != null;
			case BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_INTERFACE:
				return WEB_SERVICE_INTERFACE_EDEFAULT == null ? webServiceInterface != null : !WEB_SERVICE_INTERFACE_EDEFAULT.equals(webServiceInterface);
			case BlipDSLPackage.BLIP_SERVICE_TASK__WEB_SERVICE_OPERATION:
				return WEB_SERVICE_OPERATION_EDEFAULT == null ? webServiceOperation != null : !WEB_SERVICE_OPERATION_EDEFAULT.equals(webServiceOperation);
		}
		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(" (executionMode: ");
		result.append(executionMode);
		result.append(", timeoutInSecs: ");
		result.append(timeoutInSecs);
		result.append(", webServiceInterface: ");
		result.append(webServiceInterface);
		result.append(", webServiceOperation: ");
		result.append(webServiceOperation);
		result.append(')');
		return result.toString();
	}

} //BlipServiceTaskImpl
