package org.eclipse.jdt.internal.core.hierarchy;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;

import org.eclipse.jdt.internal.compiler.HierarchyResolver;
import org.eclipse.jdt.internal.compiler.IHierarchyRequestor;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.IGenericType;

import org.eclipse.jdt.core.*;
import org.eclipse.jdt.internal.core.*;

import java.util.Hashtable;
import java.util.Vector;

import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;

public abstract class HierarchyBuilder implements IHierarchyRequestor {
	/**
	 * The hierarchy being built.
	 */
	protected TypeHierarchy hierarchy;
	
	/**
	 * The name environment used by the HierarchyResolver
	 */
	protected SearchableEnvironment searchableEnvironment;

	/**
	 * @see INameLookup
	 */
	protected INameLookup nameLookup;

	/**
	 * The resolver used to resolve type hierarchies
	 * @see HierarchyResolver
	 */
	protected HierarchyResolver hierarchyResolver;

	/**
	 * A temporary cache of infos to handles to speed info
	 * to handle translation - it only contains the entries
	 * for the types in the region (i.e. no supertypes outside
	 * the region).
	 */
	protected Hashtable infoToHandle;
public HierarchyBuilder(TypeHierarchy hierarchy) throws JavaModelException {
	this.hierarchy = hierarchy;
	JavaProject project = (JavaProject)hierarchy.javaProject();
	this.searchableEnvironment = (SearchableEnvironment)project.getSearchableNameEnvironment();
	this.nameLookup = project.getNameLookup();
	this.hierarchyResolver = 
		new HierarchyResolver(this.searchableEnvironment, this, new DefaultProblemFactory());
	this.infoToHandle = new Hashtable(5);
}
public abstract void build(boolean computeSubtypes) throws JavaModelException, CoreException;
/**
 * Configure this type hierarchy by computing the supertypes only.
 */
protected void buildSupertypes() {
	IType focusType = this.getType();
	if (focusType == null) return;
	
	// get generic type from focus type
	IGenericType type;
	try {
		type = (IGenericType)((JavaElement) focusType).getRawInfo();
	} catch (JavaModelException e) {
		// if the focus type is not present, or if cannot get workbench path
		// we cannot create the hierarchy
		return;
	}

	// resolve
	this.searchableEnvironment.unitToLookInside = (CompilationUnit)focusType.getCompilationUnit();
	this.hierarchyResolver.resolve(type);
	this.searchableEnvironment.unitToLookInside = null;

	// Add focus if not already in (case of a type with no explicit super type)
	if (!this.hierarchy.contains(focusType)) {
		this.hierarchy.addRootClass(focusType);
	}
}
/**
 * @see IHierarchyRequestor
 */
public void connect(IGenericType suppliedType, IGenericType superclass, IGenericType[] superinterfaces) {

	this.worked(1);
	
	// convert all infos to handles
	IType typeHandle= getHandle(suppliedType);

	/*
	 * Temporary workaround for 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class
	 */
	if (typeHandle == null) return;
	
	IType superHandle= null;
	if (superclass != null) {
		superHandle= getHandle(superclass);
	}
	IType[] interfaceHandles= null;
	if (superinterfaces != null && superinterfaces.length > 0) {
		interfaceHandles= new IType[superinterfaces.length];
		for (int i= 0; i < interfaceHandles.length; i++) {
			interfaceHandles[i]= getHandle(superinterfaces[i]);
		}
	}

	// now do the caching
	if (suppliedType.isClass()) {
		if (superHandle == null) {
			this.hierarchy.addRootClass(typeHandle);
		} else {
			this.hierarchy.cacheSuperclass(typeHandle, superHandle);
		}
	} else {
		this.hierarchy.addInterface(typeHandle);
	}

	if (interfaceHandles == null) {
		interfaceHandles= this.hierarchy.fgEmpty;
	}
	this.hierarchy.cacheSuperInterfaces(typeHandle, interfaceHandles);
}
/**
 * Returns a handle for the given generic type or null if not found.
 */
protected IType getHandle(IGenericType genericType) {
	if (genericType.isBinaryType()) {
		IClassFile classFile = (IClassFile)this.infoToHandle.get(genericType);
		// if it's null, it's from outside the region, so do lookup
		if (classFile == null) {
			IType handle = lookupBinaryHandle((IBinaryType)genericType);
			if (handle == null) return null; // case of an anonymous type (see 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class)
			
			// optimization: remember the handle for next call (case of java.io.Serializable that a lot of classes implement)
			this.infoToHandle.put(genericType, handle.getParent());
			return handle;
		} else {
			try {
				return classFile.getType();
			} catch (JavaModelException e) {
				return null;
			}
		}
	} else if (genericType instanceof SourceTypeElementInfo) {
		return ((SourceTypeElementInfo)genericType).getHandle();
	} else 
		return null;
}
protected IType getType() {
	return this.hierarchy.getType();
}
/**
 * Looks up and returns a handle for the given binary info.
 */
protected IType lookupBinaryHandle(IBinaryType typeInfo) {
	int flag;
	String qualifiedName;
	if (typeInfo.isClass()) {
		flag = this.nameLookup.ACCEPT_CLASSES;
	} else {
		flag = this.nameLookup.ACCEPT_INTERFACES;
	}
	char[] bName = typeInfo.getName();
	qualifiedName = new String(ClassFile.translatedName(bName));
	return this.nameLookup.findType(qualifiedName, false, flag);
}
protected void worked(int work) {
	IProgressMonitor progressMonitor = this.hierarchy.fProgressMonitor;
	if (progressMonitor != null) {
		if (progressMonitor.isCanceled()) {
			throw new OperationCanceledException();
		} else {
			progressMonitor.worked(work);
		}
	}
}
}
