/*******************************************************************************
 * Copyright (c) 2001, 2004 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.wst.wsdl.internal.impl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.Part;
import org.eclipse.wst.wsdl.WSDLPackage;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDTypeDefinition;
import org.w3c.dom.Element;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Part</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.wsdl.impl.PartImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.PartImpl#getElementName <em>Element Name</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.PartImpl#getTypeName <em>Type Name</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.PartImpl#getTypeDefinition <em>Type Definition</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.PartImpl#getElementDeclaration <em>Element Declaration</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.PartImpl#getEMessage <em>EMessage</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class PartImpl extends WSDLElementImpl implements Part
{
  /**
   * This class is not intended to be serialized.
   * serialVersionUID is assigned with 1L to avoid
   * compiler warning messages.
   */
  private static final long serialVersionUID = 1L;

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

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

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

  /**
   * The cached value of the '{@link #getElementName() <em>Element Name</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getElementName()
   * @generated
   * @ordered
   */
  protected QName elementName = ELEMENT_NAME_EDEFAULT;

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

  /**
   * The cached value of the '{@link #getTypeName() <em>Type Name</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getTypeName()
   * @generated
   * @ordered
   */
  protected QName typeName = TYPE_NAME_EDEFAULT;

  /**
   * The cached value of the '{@link #getTypeDefinition() <em>Type Definition</em>}' reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getTypeDefinition()
   * @generated
   * @ordered
   */
  protected XSDTypeDefinition typeDefinition = null;

  /**
   * The cached value of the '{@link #getElementDeclaration() <em>Element Declaration</em>}' reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getElementDeclaration()
   * @generated
   * @ordered
   */
  protected XSDElementDeclaration elementDeclaration = null;

  /**
   * The cached value of the '{@link #getEMessage() <em>EMessage</em>}' reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEMessage()
   * @generated
   * @ordered
   */
  protected Message eMessage = null;

  public static final String NS_URI_PART_EXTENSIONS = "http://schemas.xmlsoap.org/wsdl/part-extensions/";
  public static final String ATTR_MESSAGE = "message";
  private Map extensionAttributes = new ExtensionAttributeMap();

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  protected EClass eStaticClass()
  {
    return WSDLPackage.eINSTANCE.getPart();
  }

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setName(String newName)
  {
    String oldName = name;
    name = newName;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.PART__NAME, oldName, name));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public QName getElementName()
  {
    return elementName;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setElementName(QName newElementName)
  {
    QName oldElementName = elementName;
    elementName = newElementName;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.PART__ELEMENT_NAME, oldElementName, elementName));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public QName getTypeName()
  {
    return typeName;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setTypeName(QName newTypeName)
  {
    QName oldTypeName = typeName;
    typeName = newTypeName;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.PART__TYPE_NAME, oldTypeName, typeName));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDTypeDefinition getTypeDefinition()
  {
    if (typeDefinition != null && typeDefinition.eIsProxy())
    {
      XSDTypeDefinition oldTypeDefinition = typeDefinition;
      typeDefinition = (XSDTypeDefinition)eResolveProxy((InternalEObject)typeDefinition);
      if (typeDefinition != oldTypeDefinition)
      {
        if (eNotificationRequired())
          eNotify(new ENotificationImpl(this, Notification.RESOLVE, WSDLPackage.PART__TYPE_DEFINITION, oldTypeDefinition, typeDefinition));
      }
    }
    return typeDefinition;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDTypeDefinition basicGetTypeDefinition()
  {
    return typeDefinition;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setTypeDefinition(XSDTypeDefinition newTypeDefinition)
  {
    XSDTypeDefinition oldTypeDefinition = typeDefinition;
    typeDefinition = newTypeDefinition;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.PART__TYPE_DEFINITION, oldTypeDefinition, typeDefinition));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDElementDeclaration getElementDeclaration()
  {
    if (elementDeclaration != null && elementDeclaration.eIsProxy())
    {
      XSDElementDeclaration oldElementDeclaration = elementDeclaration;
      elementDeclaration = (XSDElementDeclaration)eResolveProxy((InternalEObject)elementDeclaration);
      if (elementDeclaration != oldElementDeclaration)
      {
        if (eNotificationRequired())
          eNotify(new ENotificationImpl(this, Notification.RESOLVE, WSDLPackage.PART__ELEMENT_DECLARATION, oldElementDeclaration, elementDeclaration));
      }
    }
    return elementDeclaration;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDElementDeclaration basicGetElementDeclaration()
  {
    return elementDeclaration;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setElementDeclaration(XSDElementDeclaration newElementDeclaration)
  {
    XSDElementDeclaration oldElementDeclaration = elementDeclaration;
    elementDeclaration = newElementDeclaration;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.PART__ELEMENT_DECLARATION, oldElementDeclaration, elementDeclaration));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Message getEMessage()
  {
    if (eMessage != null && eMessage.eIsProxy())
    {
      Message oldEMessage = eMessage;
      eMessage = (Message)eResolveProxy((InternalEObject)eMessage);
      if (eMessage != oldEMessage)
      {
        if (eNotificationRequired())
          eNotify(new ENotificationImpl(this, Notification.RESOLVE, WSDLPackage.PART__EMESSAGE, oldEMessage, eMessage));
      }
    }
    return eMessage;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Message basicGetEMessage()
  {
    return eMessage;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setEMessage(Message newEMessage)
  {
    Message oldEMessage = eMessage;
    eMessage = newEMessage;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.PART__EMESSAGE, oldEMessage, eMessage));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setExtensionAttribute(QName name, QName value)
  {
    String localName = name.getLocalPart();
    if (localName == null)
      return;

    if (value == null)
      extensionAttributes.remove(name);
    else
      extensionAttributes.put(name, value);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Iterator getExtensionAttributeNames()
  {
    Map map = new HashMap(extensionAttributes);

    // Adjust messageName attribute
    QName messageName = getMessage() != null ? getMessage().getQName() : null;
    if (messageName != null)
      map.put(new QName(NS_URI_PART_EXTENSIONS, ATTR_MESSAGE), messageName);
    else
      map.remove(new QName(NS_URI_PART_EXTENSIONS, ATTR_MESSAGE));

    return map.keySet().iterator();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public QName getExtensionAttribute(QName name)
  {
    if (name.equals(new QName(NS_URI_PART_EXTENSIONS, ATTR_MESSAGE)))
      return getMessage() != null ? getMessage().getQName() : null;
    else
      return (QName) extensionAttributes.get(name);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setMessage(javax.wsdl.Message message)
  {
    setEMessage((Message) message);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Message getMessage()
  {
    return getEMessage();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Object eGet(EStructuralFeature eFeature, boolean resolve)
  {
    switch (eDerivedStructuralFeatureID(eFeature))
    {
      case WSDLPackage.PART__DOCUMENTATION_ELEMENT:
        return getDocumentationElement();
      case WSDLPackage.PART__ELEMENT:
        return getElement();
      case WSDLPackage.PART__NAME:
        return getName();
      case WSDLPackage.PART__ELEMENT_NAME:
        return getElementName();
      case WSDLPackage.PART__TYPE_NAME:
        return getTypeName();
      case WSDLPackage.PART__TYPE_DEFINITION:
        if (resolve) return getTypeDefinition();
        return basicGetTypeDefinition();
      case WSDLPackage.PART__ELEMENT_DECLARATION:
        if (resolve) return getElementDeclaration();
        return basicGetElementDeclaration();
      case WSDLPackage.PART__EMESSAGE:
        if (resolve) return getEMessage();
        return basicGetEMessage();
    }
    return eDynamicGet(eFeature, resolve);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void eSet(EStructuralFeature eFeature, Object newValue)
  {
    switch (eDerivedStructuralFeatureID(eFeature))
    {
      case WSDLPackage.PART__DOCUMENTATION_ELEMENT:
        setDocumentationElement((Element)newValue);
        return;
      case WSDLPackage.PART__ELEMENT:
        setElement((Element)newValue);
        return;
      case WSDLPackage.PART__NAME:
        setName((String)newValue);
        return;
      case WSDLPackage.PART__ELEMENT_NAME:
        setElementName((QName)newValue);
        return;
      case WSDLPackage.PART__TYPE_NAME:
        setTypeName((QName)newValue);
        return;
      case WSDLPackage.PART__TYPE_DEFINITION:
        setTypeDefinition((XSDTypeDefinition)newValue);
        return;
      case WSDLPackage.PART__ELEMENT_DECLARATION:
        setElementDeclaration((XSDElementDeclaration)newValue);
        return;
      case WSDLPackage.PART__EMESSAGE:
        setEMessage((Message)newValue);
        return;
    }
    eDynamicSet(eFeature, newValue);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void eUnset(EStructuralFeature eFeature)
  {
    switch (eDerivedStructuralFeatureID(eFeature))
    {
      case WSDLPackage.PART__DOCUMENTATION_ELEMENT:
        setDocumentationElement(DOCUMENTATION_ELEMENT_EDEFAULT);
        return;
      case WSDLPackage.PART__ELEMENT:
        setElement(ELEMENT_EDEFAULT);
        return;
      case WSDLPackage.PART__NAME:
        setName(NAME_EDEFAULT);
        return;
      case WSDLPackage.PART__ELEMENT_NAME:
        setElementName(ELEMENT_NAME_EDEFAULT);
        return;
      case WSDLPackage.PART__TYPE_NAME:
        setTypeName(TYPE_NAME_EDEFAULT);
        return;
      case WSDLPackage.PART__TYPE_DEFINITION:
        setTypeDefinition((XSDTypeDefinition)null);
        return;
      case WSDLPackage.PART__ELEMENT_DECLARATION:
        setElementDeclaration((XSDElementDeclaration)null);
        return;
      case WSDLPackage.PART__EMESSAGE:
        setEMessage((Message)null);
        return;
    }
    eDynamicUnset(eFeature);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean eIsSet(EStructuralFeature eFeature)
  {
    switch (eDerivedStructuralFeatureID(eFeature))
    {
      case WSDLPackage.PART__DOCUMENTATION_ELEMENT:
        return DOCUMENTATION_ELEMENT_EDEFAULT == null ? documentationElement != null : !DOCUMENTATION_ELEMENT_EDEFAULT.equals(documentationElement);
      case WSDLPackage.PART__ELEMENT:
        return ELEMENT_EDEFAULT == null ? element != null : !ELEMENT_EDEFAULT.equals(element);
      case WSDLPackage.PART__NAME:
        return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
      case WSDLPackage.PART__ELEMENT_NAME:
        return ELEMENT_NAME_EDEFAULT == null ? elementName != null : !ELEMENT_NAME_EDEFAULT.equals(elementName);
      case WSDLPackage.PART__TYPE_NAME:
        return TYPE_NAME_EDEFAULT == null ? typeName != null : !TYPE_NAME_EDEFAULT.equals(typeName);
      case WSDLPackage.PART__TYPE_DEFINITION:
        return typeDefinition != null;
      case WSDLPackage.PART__ELEMENT_DECLARATION:
        return elementDeclaration != null;
      case WSDLPackage.PART__EMESSAGE:
        return eMessage != null;
    }
    return eDynamicIsSet(eFeature);
  }

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

    StringBuffer result = new StringBuffer(super.toString());
    result.append(" (name: ");
    result.append(name);
    result.append(", elementName: ");
    result.append(elementName);
    result.append(", typeName: ");
    result.append(typeName);
    result.append(')');
    return result.toString();
  }

  public Map getExtensionAttributes()
  {
    return extensionAttributes;
  }

  class ExtensionAttributeMap extends HashMap
  {
    /**
     * This class is not intended to be serialized.
     * serialVersionUID is assigned with 1L to avoid
     * compiler warning messages.
     */
    private static final long serialVersionUID = 1L;

    ExtensionAttributeMap()
    {
      super();
    }

    public Object put(Object key, Object val)
    {
      QName name = (QName) key;
      QName value = (QName) val;
      String lName = name.getLocalPart();
      String nSpace = name.getNamespaceURI();

      if (NS_URI_PART_EXTENSIONS.equals(nSpace) && ATTR_MESSAGE.equals(lName))
      {
        javax.wsdl.Message messageProxy = new MessageImpl();
        messageProxy.setQName(value);
        setEMessage((Message) messageProxy);
      }
      return super.put(key, value);
    }
  }

  //
  // Reconcile methods
  //
  public void reconcileAttributes(Element changedElement)
  {
    Definition definition = getEnclosingDefinition();

    String name = changedElement.getAttributeNS(null, "name");
    if (name != null)
    {
      setName(name);
    }

    String elementAttr = WSDLConstants.getAttribute(changedElement, WSDLConstants.ELEMENT_ATTRIBUTE);
    setElementName(elementAttr != null ? createQName(definition, elementAttr, element) : null);
		    
    String typeAttr = WSDLConstants.getAttribute(changedElement, WSDLConstants.TYPE_ATTRIBUTE);
    setTypeName(typeAttr != null ? createQName(definition, typeAttr, element) : null);

    reconcileReferences(false);
  }


  //
  // For reconciliation: Model -> DOM
  //

  protected void changeAttribute(EAttribute eAttribute)
  {
    if (isReconciling)
      return;

    //super.changeAttribute(eAttribute);
    Element theElement = getElement();
    if (theElement != null)
    {
      if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getPart_Name())
        niceSetAttribute(theElement, WSDLConstants.NAME_ATTRIBUTE, getName());

      if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getPart_TypeName())
        if (getTypeName() != null)
          niceSetAttributeURIValue(theElement, WSDLConstants.TYPE_ATTRIBUTE, getTypeName().getNamespaceURI() + "#" + getTypeName().getLocalPart());
        
      if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getPart_ElementName())
        if (getElementName() != null)
          niceSetAttributeURIValue(theElement, WSDLConstants.ELEMENT_ATTRIBUTE, getElementName().getNamespaceURI() + "#" + getElementName().getLocalPart());
        
    }
  }

  protected void changeReference(EReference eReference)
  {
    if (isReconciling)
      return;

    super.changeReference(eReference);
    Element theElement = getElement();
    if (theElement != null)
    {
      if (eReference == null || eReference == WSDLPackage.eINSTANCE.getPart_TypeDefinition())
      {
        XSDTypeDefinition typeDefinition = getTypeDefinition();
        if (typeDefinition != null)
        {
          niceSetAttributeURIValue(theElement, WSDLConstants.TYPE_ATTRIBUTE, typeDefinition.getURI());
        }
      }
      if (eReference == null || eReference == WSDLPackage.eINSTANCE.getPart_ElementDeclaration())
      {
        XSDElementDeclaration elementDecl = getElementDeclaration();
        if (elementDecl != null)
        {
          niceSetAttributeURIValue(theElement, WSDLConstants.ELEMENT_ATTRIBUTE, elementDecl.getURI());
        }
      }      
    }
  }

  public Element createElement()
  {
    Element newElement = createElement(WSDLConstants.PART);
    setElement(newElement);
    return newElement;
  }

  public void reconcileReferences(boolean deep)
  {
    XSDElementDeclaration newElementDeclaration = resolveElementDeclaration(elementName);
    if (newElementDeclaration != elementDeclaration)
    {
      setElementDeclaration(newElementDeclaration);
    }

    XSDTypeDefinition newTypeDefinition = resolveTypeDefinition(typeName);
    if (newTypeDefinition != typeDefinition)
    {
      setTypeDefinition(newTypeDefinition);
    }

    super.reconcileReferences(deep);
  }

  private XSDElementDeclaration resolveElementDeclaration(QName qname)
  {
    XSDElementDeclaration result = null;
    if (qname != null)
    {
      DefinitionImpl definition = (DefinitionImpl) getEnclosingDefinition();
      if (definition != null)
      {
        result = definition.resolveElementDeclaration(qname.getNamespaceURI(), qname.getLocalPart());
      }
    }
    return result;
  }

  private XSDTypeDefinition resolveTypeDefinition(QName qname)
  {
    XSDTypeDefinition result = null;
    if (qname != null)
    {
      DefinitionImpl definition = (DefinitionImpl) getEnclosingDefinition();
      if (definition != null)
      {
        result = definition.resolveTypeDefinition(qname.getNamespaceURI(), qname.getLocalPart());
      }
    }
    return result;
  }
} //PartImpl
