/*******************************************************************************
 * 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;
/*
 *  $RCSfile: JDOMAdaptor.java,v $
 *  $Revision: 1.7 $  $Date: 2005/09/14 23:30:27 $ 
 */

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.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.
	}
	/**
	 * 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.
	 *
	 */
	public static String signatureToString(String signature) throws IllegalArgumentException {
		boolean hasDollar = (signature.indexOf(Signature.C_DOLLAR) != -1);
		String result = Signature.toString(signature);
		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);
	}
}
