/*******************************************************************************
 * 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.8 $  $Date: 2005/10/18 14:58:18 $ 
 */

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.
	 *
	 */
	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);
	}
}
