/*******************************************************************************
 * 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, WSDLConstants.NAME_ATTRIBUTE);
    if (name != null)
    {
      setName(name);
    }

    String elementAttr = WSDLConstants.getAttribute(changedElement, WSDLConstants.ELEMENT_ATTRIBUTE);
    setElementName(elementAttr != null ? createQName(definition, elementAttr, element, true) : null);
		    
    String typeAttr = WSDLConstants.getAttribute(changedElement, WSDLConstants.TYPE_ATTRIBUTE);
    setTypeName(typeAttr != null ? createQName(definition, typeAttr, element, true) : 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
