/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/
package org.eclipse.jst.jsf.context.symbol.internal.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.types.TypeInfoCache;
import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
import org.eclipse.jst.jsf.common.util.JDTBeanProperty;
import org.eclipse.jst.jsf.common.util.TypeUtil;
import org.eclipse.jst.jsf.context.symbol.IBeanMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IBeanPropertySymbol;
import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2;
import org.eclipse.jst.jsf.context.symbol.IObjectSymbol;
import org.eclipse.jst.jsf.context.symbol.IPropertySymbol;
import org.eclipse.jst.jsf.context.symbol.SymbolFactory;
import org.eclipse.jst.jsf.context.symbol.SymbolPackage;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>IJava Type Descriptor2</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IJavaTypeDescriptor2Impl#getType <em>Type</em>}</li>
 *   <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IJavaTypeDescriptor2Impl#getBeanProperties <em>Bean Properties</em>}</li>
 *   <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IJavaTypeDescriptor2Impl#getBeanMethods <em>Bean Methods</em>}</li>
 *   <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IJavaTypeDescriptor2Impl#getArrayCount <em>Array Count</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class IJavaTypeDescriptor2Impl extends ITypeDescriptorImpl implements IJavaTypeDescriptor2 {

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @SuppressWarnings("hiding")
	public static final String copyright = "Copyright 2006 Oracle";  //$NON-NLS-1$

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

    /**
     * The cached value of the '{@link #getType() <em>Type</em>}' attribute.
     * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
     * @see #getType()
     * @generated
     * @ordered
     */
	protected IType type = TYPE_EDEFAULT;

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

    /**
     * The cached value of the '{@link #getArrayCount() <em>Array Count</em>}' attribute.
     * <!-- begin-user-doc -->
     * records the array nesting of the type.  IType doesn't encapsulate
     * array types. So if this type is an array then type will represent
     * the base element and this value will be > 0.  If not an array, then
     * _arrayCount is always 0. 
     * <!-- end-user-doc -->
     * @see #getArrayCount()
     * @generated
     * @ordered
     */
    protected int arrayCount = ARRAY_COUNT_EDEFAULT;

    /**
     * The default value of the '{@link #getJdtContext() <em>Jdt Context</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #getJdtContext()
     * @generated
     * @ordered
     */
    @SuppressWarnings("hiding")
	protected static final IJavaElement JDT_CONTEXT_EDEFAULT = null;

    /**
     * The cached value of the '{@link #getJdtContext() <em>Jdt Context</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #getJdtContext()
     * @generated
     * @ordered
     */
    @SuppressWarnings("hiding")
	protected IJavaElement jdtContext = JDT_CONTEXT_EDEFAULT;

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

    /**
     * <!-- begin-user-doc -->
     * @return the static class 
	 * <!-- end-user-doc -->
     * @generated
     */
	protected EClass eStaticClass() {
        return SymbolPackage.Literals.IJAVA_TYPE_DESCRIPTOR2;
    }

    /**
     * <!-- begin-user-doc -->
     * @return the JDT type descriptor; if type is an array then this type
     * represent's the array base type only
	 * <!-- end-user-doc -->
     * @generated
     */
	public IType getType() {
        return type;
    }

    /**
     * <!-- begin-user-doc -->
     * @param newType 
	 * <!-- end-user-doc -->
     * @generated
     */
	public void setType(IType newType) {
        IType oldType = type;
        type = newType;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE, oldType, type));
    }

	/**
	 * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getInterfaceTypeSignatures()
	 * @generated NOT
	 */
	public EList getInterfaceTypeSignatures() 
    {
        EList  interfaces = new BasicEList();
        
        IType type_ = getType();
        
        if (type_ != null)
        {
            final TypeInfoCache typeInfoCache = TypeInfoCache.getInstance();
            IType[] interfaceTypes = typeInfoCache.getCachedInterfaceTypes(type_);
            if (interfaceTypes == null) {
               interfaceTypes = typeInfoCache.cacheInterfaceTypesFor(type_);
            }
            copySignatures(interfaces, interfaceTypes);
        }
        
        return interfaces;
    }

    /**
     * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getSuperTypeSignatures()
     * @generated NOT
     */
    public EList getSuperTypeSignatures() 
    {
        EList  interfaces = new BasicEList();
        
        IType type_ = getType();
        
        if (type_ != null)
        {
            final TypeInfoCache typeInfoCache = TypeInfoCache.getInstance();
            IType[] interfaceTypes = typeInfoCache.getCachedSupertypes(type_);

            if (interfaceTypes == null) 
            {
               interfaceTypes = typeInfoCache.cacheSupertypesFor(type_);
            }
            copySignatures(interfaces, interfaceTypes);
        }
        
        return interfaces;
    }
    
    
    private void copySignatures(List  list, IType[]  types)
    {
        if (types != null)
        {
            for (int i = 0; i < types.length; i++)
            {
                final IType type_ = types[i];
                final String signature = TypeUtil.getSignature(type_);

                if (signature != null)
                {
                    list.add(signature);
                }
            }
        }
    }

    public EList getProperties() 
    {
        return getBeanProperties();
    }

    
    public EList getMethods() 
    {
        return getBeanMethods();
    }

    /**
	 * <!-- begin-user-doc -->
     * @return the bean props for this java type 
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public EList getBeanProperties() 
	{
	    TypeInfoCache typeInfoCache = TypeInfoCache.getInstance();
	    IBeanPropertySymbol[] properties = typeInfoCache.getCachedPropertySymbols(type);
	    Collection propertyColl;
	    if (properties == null) {
	        propertyColl = getPropertiesInternal();
	        properties = (IBeanPropertySymbol[]) propertyColl.toArray(new IBeanPropertySymbol[propertyColl.size()]);
	        typeInfoCache.cachePropertySymbols(type, properties);
	    } 
	    else 
	    {
            propertyColl = new ArrayList(properties.length);
            Collections.addAll(propertyColl, (Object[])properties);
	    }
	    BasicEList list = new BasicEList(propertyColl);
	    return list;
	}

	/**
	 * <!-- begin-user-doc -->
     * @return the bean methods for this type  
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public EList getBeanMethods() {
	    TypeInfoCache typeInfoCache = TypeInfoCache.getInstance();
	    IBeanMethodSymbol[] methods = typeInfoCache.getCachedMethodSymbols(type);
	    Collection methodColl;
	    if (methods == null) 
	    {
	        methodColl = getMethodsInternal();
	        methods = (IBeanMethodSymbol[]) methodColl.toArray(new IBeanMethodSymbol[methodColl.size()]);
	        typeInfoCache.cacheMethodSymbols(type, methods);
	    } else {
	        methodColl = new ArrayList(methods.length);
	        Collections.addAll(methodColl, (Object[])methods);
	    }
	    BasicEList list = new BasicEList(methodColl);
		return list;
	}

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

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    public void setArrayCount(int newArrayCount) {
        int oldArrayCount = arrayCount;
        arrayCount = newArrayCount;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT, oldArrayCount, arrayCount));
    }

	/**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    public IJavaElement getJdtContext() {
        return jdtContext;
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    public void setJdtContext(IJavaElement newJdtContext) {
        IJavaElement oldJdtContext = jdtContext;
        jdtContext = newJdtContext;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__JDT_CONTEXT, oldJdtContext, jdtContext));
    }

    /**
     * <!-- begin-user-doc -->
     * 
     * Tries to load an IType for a fully resolved (i.e. starts with L not Q)
     * type signature using the current jdtContext.
     * 
     * @return the resolved IType or null if none could be resolved.
     * 
     * <!-- end-user-doc -->
     * @generated NOT
     */
    public IType resolveType(String resolvedTypeSignature) 
    {
        IType resolvedType = null;
        
        // we need to obtain an IJavaProject within which to resolve
        // the type.
        IJavaProject project = null;
        
        // first, see if we have an IType
        if (getType() != null)
        {
            // optimize: if the type sig is my type sig, then return getType()
            if (resolvedTypeSignature.equals(getTypeSignature()))
            {
                resolvedType = getType();
            }
            else
            {
                project = getType().getJavaProject();
                
                if (project != null)
                {
                    resolvedType =  TypeUtil.resolveType(project, resolvedTypeSignature);
                }
            }
        }        
        
        // if not, see if a jdtContext hint has been set
        if (resolvedType == null && getJdtContext() != null)
        {
            resolvedType = super.resolveType(resolvedTypeSignature);
        }
        
        return resolvedType;
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    public Object eGet(int featureID, boolean resolve, boolean coreType) {
        switch (featureID) {
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE:
                return getType();
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_PROPERTIES:
                return getBeanProperties();
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_METHODS:
                return getBeanMethods();
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT:
                return Integer.valueOf(getArrayCount());
        }
        return super.eGet(featureID, resolve, coreType);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    public void eSet(int featureID, Object newValue) {
        switch (featureID) {
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE:
                setType((IType)newValue);
                return;
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_PROPERTIES:
                getBeanProperties().clear();
                getBeanProperties().addAll((Collection)newValue);
                return;
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_METHODS:
                getBeanMethods().clear();
                getBeanMethods().addAll((Collection)newValue);
                return;
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT:
                setArrayCount(((Integer)newValue).intValue());
                return;
        }
        super.eSet(featureID, newValue);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    public void eUnset(int featureID) {
        switch (featureID) {
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE:
                setType(TYPE_EDEFAULT);
                return;
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_PROPERTIES:
                getBeanProperties().clear();
                return;
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_METHODS:
                getBeanMethods().clear();
                return;
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT:
                setArrayCount(ARRAY_COUNT_EDEFAULT);
                return;
        }
        super.eUnset(featureID);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    public boolean eIsSet(int featureID) {
        switch (featureID) {
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE:
                return TYPE_EDEFAULT == null ? type != null : !TYPE_EDEFAULT.equals(type);
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_PROPERTIES:
                return !getBeanProperties().isEmpty();
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_METHODS:
                return !getBeanMethods().isEmpty();
            case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT:
                return arrayCount != ARRAY_COUNT_EDEFAULT;
        }
        return super.eIsSet(featureID);
    }

    public boolean isArray() 
    {
	    return getArrayCount() > 0;
    }

    /**
	 * @generated NOT
	 */
	public IObjectSymbol getArrayElement() 
	{
		if (isArray())
		{
			final String typeSignature = getTypeSignature();
			final int arrayCount_ = Signature.getArrayCount(typeSignature);
			final String baseType = Signature.getElementType(typeSignature);
			final String elementTypeSignature = Signature.createArraySignature(baseType, arrayCount_-1);

			final IJavaTypeDescriptor2 elementTypeDesc = 
				SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
			final String fullyQualifiedElementType = TypeUtil.getFullyQualifiedName(baseType);
			
			IType elementType = null;

			try 
			{
			    IType myType = getType();
				if (myType != null)
				{
					elementType = getType().getJavaProject()
					                 .findType(fullyQualifiedElementType);
				}
			} 
			catch (JavaModelException e) 
			{
				// suppress
			}

			if (elementType != null)
			{
				elementTypeDesc.setType(elementType);
			}
			else
			{
				elementTypeDesc.setTypeSignatureDelegate(elementTypeSignature);
			}
            
            elementTypeDesc.setArrayCount(Signature.getArrayCount(elementTypeSignature));
			
			IPropertySymbol newPropertySymbol = 
				SymbolFactory.eINSTANCE.createIPropertySymbol();
			newPropertySymbol.setTypeDescriptor(elementTypeDesc);
			newPropertySymbol.setWritable(true);
			newPropertySymbol.setReadable(true);
			newPropertySymbol.setName(fullyQualifiedElementType);
            return newPropertySymbol;
		}

		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getTypeSignature()
     * @generated NOT
	 */
	public String getTypeSignature() 
    {
        if (getType() == null)
        {
            if (eIsSet(SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE_SIGNATURE_DELEGATE))
            {
                return getTypeSignatureDelegate();
            }

            return null;
        }
       
        // make sure to array type nesting if using IType
        return Signature.createArraySignature(
                 TypeUtil.getSignature(getType()), getArrayCount());
    }

    private Collection getPropertiesInternal()
	{
        // if I'm an array then I have no bean properties
        if (isArray())
        {
            return Collections.EMPTY_LIST;
        }
        
        final JDTBeanIntrospector  introspector = 
            new JDTBeanIntrospector(getType());
        
		final Map<String, JDTBeanProperty> properties = introspector.getProperties();
		
		final Collection calculatedProps = new ArrayList(properties.size());
        
		for (final Iterator<Map.Entry<String, JDTBeanProperty>> it = properties.entrySet().iterator(); it.hasNext();)
		{
		    Map.Entry<String, JDTBeanProperty> entry = it.next();
		    final String propertyName = entry.getKey();
            final JDTBeanProperty property = entry.getValue();

			final IBeanPropertySymbol workingCopy =
			    SymbolFactory.eINSTANCE.createIBeanPropertySymbol();
			workingCopy.setName(propertyName);
			workingCopy.setOwner(this);
                        
            final IJavaTypeDescriptor2 workingCopyDesc = 
                SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
            workingCopy.setTypeDescriptor(workingCopyDesc);
			workingCopy.setReadable(property.isReadable());
            workingCopy.setWritable(property.isWritable());
                            
            workingCopyDesc.setArrayCount(property.getArrayCount());
            workingCopyDesc.getTypeParameterSignatures().addAll(property.getTypeParameterSignatures());
            workingCopyDesc.setEnumType(property.isEnumType());
           
            final IType newType = property.getType();
            final String signature = property.getTypeSignature();
            
            if (newType != null)
            {
                workingCopyDesc.setType(newType);
            }
            else
            {
                workingCopyDesc.setTypeSignatureDelegate(signature);
            }
            
            calculatedProps.add(workingCopy);
		}

		return calculatedProps;
	}

    private Collection getMethodsInternal()
	{
        JDTBeanIntrospector introspector =
            new JDTBeanIntrospector(getType());
        
		IMethod[] methods = introspector.getAllMethods();

        List methodSymbols = new ArrayList();

		for (int i = 0; i < methods.length; i++)
		{
			IMethod method = methods[i];
			
			try
			{
				// to be a bean method, it must not a constructor, must be public
				// and must not be static
				if (!method.isConstructor()
						&& Flags.isPublic(method.getFlags())
						&& !Flags.isStatic(method.getFlags()))
				{
					String methodName = method.getElementName();
					IBeanMethodSymbol workingCopy = SymbolFactory.eINSTANCE.createIBeanMethodSymbol();
					workingCopy.setName(methodName);
					workingCopy.setOwner(this);
                    workingCopy.setSignature(TypeUtil.
                                                resolveMethodSignature
                                                    (getType(), 
                                                     method.getSignature()));
					methodSymbols.add(workingCopy);
				}
			}
			catch (JavaModelException jme)
			{
				// error reading meta-data.  Skip to next one
                JSFCommonPlugin.log(jme);
			}
		}
		
		return methodSymbols;
	}


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

        StringBuffer result = new StringBuffer(super.toString());
        result.append(" (type: "); //$NON-NLS-1$
        result.append(type);
        result.append(", arrayCount: "); //$NON-NLS-1$
        result.append(arrayCount);
        result.append(')');
        return result.toString();
    }

} //IJavaTypeDescriptor2Impl
