/*******************************************************************************
 * Copyright (c) 2001, 2005 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.jem.internal.adapters.jdom;
/*


 */

import java.io.File;
import java.util.Map;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.jdt.core.*;
import org.eclipse.jem.java.*;
import org.eclipse.jem.internal.java.adapters.JavaReflectionAdaptor;
import org.eclipse.jem.internal.java.adapters.nls.ResourceHandler;
import org.eclipse.jem.java.internal.impl.JavaRefFactoryImpl;
/**
 * Insert the type's description here.
 * Creation date: (6/6/2000 4:42:50 PM)
 * @author: Administrator
 */
public abstract class JDOMAdaptor extends JavaReflectionAdaptor {

	protected final static JavaRefPackage JAVA_PACK = JavaRefFactoryImpl.getPackage();
	protected IJavaProject sourceProject;
	final public static int INVALID_LINENO = -1;
	final protected Integer fLINENOLock = new Integer(INVALID_LINENO);
	// This object is not static, as it is used as synchronization element.
	private int fResolvedLineNo = INVALID_LINENO; // Line offset in source file
	private int fResolvedColNo = INVALID_LINENO; // Column offset in source file
	public JDOMAdaptor(Notifier target, IJavaProject workingProject) {
		super(target);
		setSourceProject(workingProject);
	}
	protected void clearSource() {
		// To be overidden if needed.
	}
	
	/**
	 * Called by subclasses in canReflect(). If the target is not in a resource, or the
	 * resource is not loaded, then it can't reflect. Mustn't reflect if the target
	 * has been unloaded.
	 * 
	 * @return
	 */
	protected boolean isResourceLoaded() {
		Resource res = ((EObject) getTarget()).eResource();
		return res != null && res.isLoaded();
	}
	
	/**
	 * Scan for CRs and LFs within a character buffer
	 * Creation date: (8/17/2001 2:14:13 PM)
	 * @return int  LineNo at charOffset
	 * @param charOffset int
	 * @param buffer org.eclipse.jdt.core.IBuffer
	 */
	private void computeLineOffset(int charOffset, IBuffer buffer) {

		fResolvedColNo = fResolvedLineNo = INVALID_LINENO;

		if (buffer == null)
			return;

		char[] charBuff = buffer.getCharacters();

		if (charBuff == null)
			return;

		int LineCount = 0;
		int ColNo = 0;
		for (int i = 0; i <= charOffset; i++) {
			ColNo++;
			if (charBuff[i] == '\r') {
				LineCount++;
				ColNo = 0;
				if (charBuff[i + 1] == '\n')
					i++; // skip LineFeed followed  a CR
			} else if (charBuff[i] == '\n') {
				LineCount++;
				ColNo = 0;
			}

		}
		fResolvedColNo = ColNo;
		fResolvedLineNo = LineCount;
	}
	/**
	 * computeMethodID - generate the unique ID to be used to identify a method.
	 * Similar to a Signature, but hopefully more readable.
	 * The name format will be:
	 * 	simpleTypeName.methodName(my.package.Parm_Type1,parmType2
	 * Note: This implementation is tightly coupled with ReflectionAdapter.getTypeNamesFromMethodID().
	 */
	public static String computeMethodID(IMethod jdomMethod) {
		return computeMethodID(jdomMethod, jdomMethod.getDeclaringType(), null);
	}
	/**
	 * computeMethodID - generate the unique ID to be used to identify a method.
	 * Similar to a Signature, but hopefully more readable.
	 * The name format will be:
	 * 	simpleTypeName.methodName(my.package.Parm_Type1,parmType2
	 * Note: This implementation is tightly coupled with ReflectionAdapter.getTypeNamesFromMethodID().
	 */
	public static String computeMethodID(IMethod jdomMethod, IType type, Map typeCache) {
		StringBuffer out = new StringBuffer();
		out.append(type.getTypeQualifiedName());
		out.append(C_CLASS_MEMBER_DELIMITER);
		out.append(jdomMethod.getElementName());
		out.append(C_METHOD_PARM_DELIMITER);
		String[] parmTypeNames = jdomMethod.getParameterTypes();
		String parmName;
		for (int i = 0; i < parmTypeNames.length; i++) {
			parmName = convertJDOMtypeName(parmTypeNames[i]);
			parmName = JDOMSearchHelper.getResolvedTypeName(parmName, type, typeCache);
			out.append(parmName);
			if (i < (parmTypeNames.length - 1))
				out.append(C_PARM_PARM_DELIMITER);
		}
		try {
			if (jdomMethod.isConstructor())
				out.append(S_CONSTRUCTOR_TOKEN);
		} catch (JavaModelException e) {
		}
		return out.toString();
	}
	/**
	 * computeMethodName - generate the name to be used to identify a method.
	 * For the moment, names are simple, and UUID's are complex.
	 */
	public static String computeMethodName(IMethod jdomMethod) {
		return jdomMethod.getElementName();
	}
	/**
	 * Java content has changed, but no structural changes that require
	 * to reflectValues();  e.g., the body of a method has changed.
	 * Creation date: (8/17/2001 10:47:58 AM)
	 */
	public void contentChanged() {
		synchronized (fLINENOLock) {
			fResolvedLineNo = INVALID_LINENO;
			fResolvedColNo = INVALID_LINENO;
		}
	}
	/**
	 * computeMethodID - generate the unique ID to be used to identify a method.
	 * Similar to a Signature, but hopefully more readable.
	 * The name format will be:
	 * 	methodName_parmType1_parmType2
	 */
	public static String convertJDOMtypeName(String jdomTypeName) {
		return signatureToString(jdomTypeName);
	}
	/**
	 * createJavaField - instantiate a Java Field based on the passed Java Model IField
	 * We are deferring field contents assuming that its adaptor will reflect its details.
	 */
	public Field createJavaField(IField jdomField, XMIResource resource) {
		String name = jdomField.getElementName();
		Field newField = getJavaFactory().createField();
		newField.setName(name);
		resource.setID(newField, ((JavaClass) getTarget()).getName() + C_CLASS_MEMBER_DELIMITER + name);
		return newField;
	}
	/**
	 * createJavaMethod - instantiate a Java Method based on the passed Java Model IMethod
	 * We are deferring method contents assuming that its adaptor will reflect its details.
	 * We need to store enough info in the empty Method to find its Java source.
	 * The UUID will eventually hold enough info to identify the source, so we use it.
	 */
	public Method createJavaMethod(IMethod jdomMethod, XMIResource resource) {
		Method newMethod = getJavaFactory().createMethod();
		// We use a simple name, but a complex ID 
		newMethod.setName(computeMethodName(jdomMethod));
		resource.setID(newMethod, computeMethodID(jdomMethod, getType(), getTypeResolutionCache()));
		return newMethod;
	}
	protected IPath getBinaryPathFromQualifiedName(String qualifiedName) {
		return new Path(qualifiedName.replace('.', File.separatorChar) + ".class"); //$NON-NLS-1$
	}
	public IType getBinaryType(String qualifiedName) {
		try {
			if (getSourceProject() != null) {
				IJavaElement found = getSourceProject().findElement(getBinaryPathFromQualifiedName(qualifiedName));
				if (found != null)
					return ((IClassFile) found).getType();
			}
		} catch (JavaModelException jme) {
			System.out.println(ResourceHandler.getString("Error_Looking_Up_Type_ERROR_", (new Object[] { qualifiedName, jme.getMessage()}))); //$NON-NLS-1$ = "Error looking up type: "
		}
		return null;
	}
	/**
	 * Compute a column number from the ISourceRange offset
	 * Cache the line number thereafter.  Source change will
	 * Invoke the contentChanged() method.
	 * Creation date: (8/17/2001 11:16:51 AM)
	 * @return int
	 */
	public int getColNo() {

		synchronized (fLINENOLock) {
			if (fResolvedColNo == INVALID_LINENO)
				resolveLineColNo();
		}
		return fResolvedColNo;
	}
	/**
	 * Compute a line number from the ISourceRange offset
	 * Cache the line number thereafter.  Source change will
	 * Invoke the contentChanged() method.
	 * Creation date: (8/17/2001 11:16:51 AM)
	 * @return int
	 */
	public int getLineNo() {

		synchronized (fLINENOLock) {
			if (fResolvedLineNo == INVALID_LINENO)
				resolveLineColNo();
		}
		return fResolvedLineNo;
	}
	/**
	 * Insert the method's description here.
	 * Creation date: (8/17/2001 1:18:29 PM)
	 */
	public abstract Object getReflectionSource();
	/* 
	 * Resolve a type name in the context of a Type.
	 * (Borrowed from org.eclipse.jdt.ui.codemanipulation.StubUtility.getResolvedTypeName())
	 * The input is a simple or qualified name, NOT a signature
	 * The output will be a qualified name, NOT a signature
	 */
	public static String getResolvedTypeName(String typeName, IType declaringType) {
		String name = typeName;
		try {
			name = JDOMSearchHelper.resolveSimpleTypeName(declaringType, typeName);
		} catch (JavaModelException e) {
			// ignore
		}
		return name;
	}

	protected IJavaProject getSourceProject() {
		return sourceProject;
	}
	protected abstract IType getType();
	protected abstract Map getTypeResolutionCache();

	public void releaseSourceType() {
		flushReflectedValuesIfNecessary(true); // induce clients to get Notified.
	}

	public Notification releaseSourceTypeNoNotification() {
		return flushReflectedValuesIfNecessaryNoNotification(true); // induce clients to get Notified.
	}
	/**
	 * Insert the method's description here.
	 * Creation date: (8/21/2001 8:09:34 AM)
	 */
	private void resolveLineColNo() {

		IMember rs = (IMember) getReflectionSource();
		if (rs != null) {
			int offset = INVALID_LINENO;
			try {
				ISourceRange sr = rs.getNameRange();
				if (sr.getLength() <= 0)
					return;
				offset = sr.getOffset();
			} catch (JavaModelException je) {
				return;
			}
			ICompilationUnit cu = rs.getCompilationUnit();
			if (cu != null) {
				try {
					IBuffer buffer = cu.getBuffer();
					computeLineOffset(offset, buffer);
				} catch (JavaModelException je) {
				}
			}
		}
	}
	protected void setSourceProject(IJavaProject workingProject) {
		sourceProject = workingProject;
	}
	/**
	 * Converts a type signature to a readable string.
	 *
	 * Uses Signature.toString(), then tries to undo bad replacement for inner classes.
	 * 
	 * Bug: 166226 [https://bugs.eclipse.org/bugs/show_bug.cgi?id=166226]
	 * Update to use the erasure type from the signature in order to 
	 * tolerate JDK 5 generics.
	 *
	 */
	public static String signatureToString(String signature) throws IllegalArgumentException {
		boolean hasDollar = (signature.indexOf(Signature.C_DOLLAR) != -1);
		//begin 166226 fix
		String result = Signature.getTypeErasure(signature);
		result = Signature.toString(result);
		//end 166226 fix
		if (hasDollar) {
			int newPos = result.lastIndexOf("."); //$NON-NLS-1$
			if (newPos != -1) {
				result = result.substring(0, newPos) + "$" + result.substring(newPos + 1); //$NON-NLS-1$
			}
		}
		return result;
	}
	/**
	 * setType - set our type here
	 */
	protected String typeNameFromSignature(String sig) {
		return typeNameFromSignature(sig, getType());
	}
	/**
	 * setType - set our type here
	 */
	protected String typeNameFromSignature(String sig, IType parent) {
		return typeNameFromSignature(sig, parent, getTypeResolutionCache());
	}
	/**
	 * setType - set our type here
	 */
	public static String typeNameFromSignature(String sig, IType parent, Map typeCache) {
		String result;
		String componentSignature = Signature.getElementType(sig);
		int arrayDimensions = Signature.getArrayCount(sig);
		result = JDOMSearchHelper.getResolvedTypeName(signatureToString(componentSignature), parent, typeCache);
		for (int i = 0; i < arrayDimensions; i++) {
			result = result + "[]"; //$NON-NLS-1$
		}
		return result;
	}
	/**
	 * @deprecated
	 * @see org.eclipse.jem.internal.adapters.jdom.JDOMSearchHelper#findType(String, boolean, IJavaProject, JDOMAdaptor)
	 */
	public IType getType(String qualifiedName) {
		return JDOMSearchHelper.findType(qualifiedName, false, getSourceProject(), this);
	}
}
