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


import java.io.IOException;
import java.io.InputStream;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Import;
import org.eclipse.wst.wsdl.WSDLFactory;
import org.eclipse.wst.wsdl.WSDLPackage;
import org.eclipse.wst.wsdl.internal.util.WSDLModelLocator;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.eclipse.wst.wsdl.util.WSDLResourceImpl;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.util.XSDResourceImpl;
import org.w3c.dom.Element;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Import</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.ImportImpl#getNamespaceURI <em>Namespace URI</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.ImportImpl#getLocationURI <em>Location URI</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.ImportImpl#getEDefinition <em>EDefinition</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.ImportImpl#getESchema <em>ESchema</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class ImportImpl extends ExtensibleElementImpl implements Import
{
  /**
   * This class is not intended to be serialized.
   * serialVersionUID is assigned with 1L to avoid
   * compiler warning messages.
   */
  private static final long serialVersionUID = 1L;

  protected boolean resolved;

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

  /**
   * The cached value of the '{@link #getNamespaceURI() <em>Namespace URI</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getNamespaceURI()
   * @generated
   * @ordered
   */
  protected String namespaceURI = NAMESPACE_URI_EDEFAULT;

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

  /**
   * The cached value of the '{@link #getLocationURI() <em>Location URI</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getLocationURI()
   * @generated
   * @ordered
   */
  protected String locationURI = LOCATION_URI_EDEFAULT;

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

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

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

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

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setNamespaceURI(String newNamespaceURI)
  {
    String oldNamespaceURI = namespaceURI;
    namespaceURI = newNamespaceURI;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.IMPORT__NAMESPACE_URI, oldNamespaceURI, namespaceURI));
  }

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setLocationURI(String newLocationURI)
  {
    String oldLocationURI = locationURI;
    locationURI = newLocationURI;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.IMPORT__LOCATION_URI, oldLocationURI, locationURI));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Definition getEDefinition()
  {
    if (eDefinition != null && eDefinition.eIsProxy())
    {
      InternalEObject oldEDefinition = (InternalEObject)eDefinition;
      eDefinition = (Definition)eResolveProxy(oldEDefinition);
      if (eDefinition != oldEDefinition)
      {
        if (eNotificationRequired())
          eNotify(new ENotificationImpl(this, Notification.RESOLVE, WSDLPackage.IMPORT__EDEFINITION, oldEDefinition, eDefinition));
      }
    }
    return eDefinition;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Definition basicGetEDefinition()
  {
    return eDefinition;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setEDefinition(Definition newEDefinition)
  {
    Definition oldEDefinition = eDefinition;
    eDefinition = newEDefinition;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.IMPORT__EDEFINITION, oldEDefinition, eDefinition));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDSchema getESchema()
  {
    if (eSchema != null && eSchema.eIsProxy())
    {
      InternalEObject oldESchema = (InternalEObject)eSchema;
      eSchema = (XSDSchema)eResolveProxy(oldESchema);
      if (eSchema != oldESchema)
      {
        if (eNotificationRequired())
          eNotify(new ENotificationImpl(this, Notification.RESOLVE, WSDLPackage.IMPORT__ESCHEMA, oldESchema, eSchema));
      }
    }
    return eSchema;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDSchema basicGetESchema()
  {
    return eSchema;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setESchema(XSDSchema newESchema)
  {
    XSDSchema oldESchema = eSchema;
    eSchema = newESchema;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.IMPORT__ESCHEMA, oldESchema, eSchema));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public XSDSchema getSchema()
  {
    return getESchema();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setSchema(XSDSchema schema)
  {
    setESchema(schema);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Object eGet(int featureID, boolean resolve, boolean coreType)
  {
    switch (featureID)
    {
      case WSDLPackage.IMPORT__NAMESPACE_URI:
      return getNamespaceURI();
      case WSDLPackage.IMPORT__LOCATION_URI:
      return getLocationURI();
      case WSDLPackage.IMPORT__EDEFINITION:
      if (resolve)
        return getEDefinition();
      return basicGetEDefinition();
      case WSDLPackage.IMPORT__ESCHEMA:
      if (resolve)
        return getESchema();
      return basicGetESchema();
    }
    return super.eGet(featureID, resolve, coreType);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void eSet(int featureID, Object newValue)
  {
    switch (featureID)
    {
      case WSDLPackage.IMPORT__NAMESPACE_URI:
      setNamespaceURI((String)newValue);
      return;
      case WSDLPackage.IMPORT__LOCATION_URI:
      setLocationURI((String)newValue);
      return;
      case WSDLPackage.IMPORT__EDEFINITION:
      setEDefinition((Definition)newValue);
      return;
      case WSDLPackage.IMPORT__ESCHEMA:
      setESchema((XSDSchema)newValue);
      return;
    }
    super.eSet(featureID, newValue);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void eUnset(int featureID)
  {
    switch (featureID)
    {
      case WSDLPackage.IMPORT__NAMESPACE_URI:
      setNamespaceURI(NAMESPACE_URI_EDEFAULT);
      return;
      case WSDLPackage.IMPORT__LOCATION_URI:
      setLocationURI(LOCATION_URI_EDEFAULT);
      return;
      case WSDLPackage.IMPORT__EDEFINITION:
      setEDefinition((Definition)null);
      return;
      case WSDLPackage.IMPORT__ESCHEMA:
      setESchema((XSDSchema)null);
      return;
    }
    super.eUnset(featureID);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean eIsSet(int featureID)
  {
    switch (featureID)
    {
      case WSDLPackage.IMPORT__NAMESPACE_URI:
      return NAMESPACE_URI_EDEFAULT == null ? namespaceURI != null : !NAMESPACE_URI_EDEFAULT.equals(namespaceURI);
      case WSDLPackage.IMPORT__LOCATION_URI:
      return LOCATION_URI_EDEFAULT == null ? locationURI != null : !LOCATION_URI_EDEFAULT.equals(locationURI);
      case WSDLPackage.IMPORT__EDEFINITION:
      return eDefinition != null;
      case WSDLPackage.IMPORT__ESCHEMA:
      return eSchema != null;
    }
    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(" (namespaceURI: "); //$NON-NLS-1$
    result.append(namespaceURI);
    result.append(", locationURI: "); //$NON-NLS-1$
    result.append(locationURI);
    result.append(')');
    return result.toString();
  }

  /**
   * @see Import#getDefinition()
   */
  public javax.wsdl.Definition getDefinition()
  {
    return getEDefinition();
  }

  /**
   * @see Import#setDefinition(Definition)
   */
  public void setDefinition(javax.wsdl.Definition definition)
  {
    setEDefinition((org.eclipse.wst.wsdl.Definition)definition);
  }

  //
  // Reconcile methods
  //
  public void reconcileAttributes(Element changedElement)
  {
    setNamespaceURI(WSDLConstants.getAttribute(changedElement, WSDLConstants.NAMESPACE_ATTRIBUTE));
    setLocationURI(WSDLConstants.getAttribute(changedElement, WSDLConstants.LOCATION_ATTRIBUTE));
  }

  //
  // For reconciliation: Model -> DOM
  //
  protected void changeAttribute(EAttribute eAttribute)
  {
    // We need to set this boolean to false because the Import may point to a different location.
    // So we need we should view this import as unresolved.
    resolved = false;

    if (isReconciling)
      return;

    super.changeAttribute(eAttribute);
    Element theElement = getElement();
    if (theElement != null)
    {
      if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getImport_NamespaceURI())
        niceSetAttribute(theElement, WSDLConstants.NAMESPACE_ATTRIBUTE, getNamespaceURI());

      if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getImport_LocationURI())
        niceSetAttribute(theElement, WSDLConstants.LOCATION_ATTRIBUTE, getLocationURI());
    }
  }

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

  public void importDefinitionOrSchema()
  {
    resolve(getNamespaceURI(), getLocationURI());
  }

  protected void resolve(String namespace, String location)
  {
    if (!resolved)
    {
      // KB: bugzilla 118293
      // If a user changes <wsdl:import> from a WSDL file to an XML Schema file
      // or the other way around, we should set the variable for the first
      // <wsdl:import> source to null. Here I am simply setting both variables to null,
      // which will have the same effect.
      eDefinition = null;
      eSchema = null;

      Definition definition = getEnclosingDefinition();
      if (definition != null && definition.getDocumentBaseURI() != null)
      {
        Resource resource = definition.eResource();
        if (resource != null)
        {
          ResourceSet resourceSet = resource.getResourceSet();
          if (resourceSet != null)
          {
            if (namespace == null)
            {
              namespace = definition.getTargetNamespace();
            }

            String resolvedLocation = resolveLocation(definition, namespace, location);

            URI uri = URI.createURI(resolvedLocation);
            Resource resolvedResource = resourceSet.getResource(uri, false);
            if (resolvedResource == null)
            {
              try
              {
                InputStream inputStream = resourceSet.getURIConverter().createInputStream(uri);
                resolvedResource = resourceSet.createResource(uri);
                resolvedResource.load(inputStream, resourceSet.getLoadOptions());
              }
              catch (IOException exception)
              {
                // It is generally not an error to fail to resolve.
                // If a resource is actually created, 
                // which happens only when we can create an input stream,
                // then it's an error if it's not a good wsdl or schema
              }
            }

            if (resolvedResource != null)
            {
              if (resolvedResource instanceof WSDLResourceImpl)
              {
                eDefinition = ((WSDLResourceImpl)resolvedResource).getDefinition();
              }
              else if (resolvedResource instanceof XSDResourceImpl)
              {
                eSchema = ((XSDResourceImpl)resolvedResource).getSchema();
              }
              else
              {
                eDefinition = WSDLFactory.eINSTANCE.createDefinition();
              }
            }
            resolved = true;
          }
        }
      }
    }
  }

  protected String resolveLocation(Definition definition, String namespace, String schemaLocation)
  {
    String result = null;
    WSDLModelLocator locator = (WSDLModelLocator)EcoreUtil.getRegisteredAdapter(definition.eResource(), WSDLModelLocator.class);
    if (locator != null)
    {
      result = locator.resolveURI(definition.getDocumentBaseURI(), namespace, schemaLocation);
    }
    else
    {
      // TODO... there's some default resolving we'll need to do here
      // see XSDSchemaDirective
      URI baseLocationURI = createURI(definition.getDocumentBaseURI());
      URI locationURI = URI.createURI(schemaLocation);
      return locationURI.resolve(baseLocationURI).toString();
    }
    return result;
  }

  //TODO... push down to EMF
  private static URI createURI(String uriString)
  {
    if (hasProtocol(uriString))
      return URI.createURI(uriString);
    else
      return URI.createFileURI(uriString);
  }

  //TODO... push down to EMF  
  private static boolean hasProtocol(String uri)
  {
    boolean result = false;
    if (uri != null)
    {
      int index = uri.indexOf(":");
      if (index != -1 && index > 2) // assume protocol with be length 3 so that the'C' in 'C:/' is not interpreted as a protocol
      {
        result = true;
      }
    }
    return result;
  }
} //ImportImpl
