package org.eclipse.jem.internal.proxy.initParser;
/*******************************************************************************
 * Copyright (c)  2001, 2003 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
 *******************************************************************************/
/*
 *  $RCSfile: Static.java,v $
 *  $Revision: 1.3 $  $Date: 2005/02/15 22:55:20 $ 
 */


import java.io.*;
import java.lang.reflect.Array;
import java.util.*;

public class Static extends Expression {
	protected static final HashMap sPrimitiveTypes;
	
	static {
		sPrimitiveTypes = new HashMap(10);
		sPrimitiveTypes.put("byte", Byte.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("char", Character.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("short", Short.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("int", Integer.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("long", Long.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("float", Float.TYPE);		 //$NON-NLS-1$
		sPrimitiveTypes.put("double", Double.TYPE); //$NON-NLS-1$
	}

	protected ArrayList arrayDimensions;
	protected List fArrayArguments;
	protected StringWriter typeWriter = new StringWriter();
	protected boolean completedWithPeriod = false;
	protected char[] completionToken;
	public Class type;
	protected boolean isComplete;

	public boolean isProcessingArrayDimension;
/**
 * Create an unknown expression
 */
public Static(ClassLoader aClassLoader){
	fClassLoader = aClassLoader;
}
public Static(char[] aToken,char delimiter,ClassLoader aClassLoader){
	
	fClassLoader = aClassLoader;
	try { 
		typeWriter.write(aToken);
	} catch ( IOException exc ) {};
	checkForValidType();
	if ( type == null && delimiter == DelimiterPeriod ){
		typeWriter.write(DelimiterPeriod);
	}
		
}
public Static(char[] aToken,char delimiter,ClassLoader aClassLoader,boolean isArray){
	this(aToken,delimiter,aClassLoader);
	isProcessingArrayDimension = true;
	arrayDimensions = new ArrayList(1);
	arrayDimensions.add(new Statement(aClassLoader));
}

public boolean isComplete(){
	return isComplete;
}
public boolean isArray(){
	return arrayDimensions != null;
}
/**
 * See whether or not we have a valid type
 * This uses the class loader given to us if one specified.  The reason for this
 * is that Eclipse uses a special plugin class loader and when we are running
 * in a VM inside eclipse ( e.g. for IDEVM proxy stuff ) we must have
 * reference to the plugin that is using us otherwise we can't load its classes
 */
protected void checkForValidType(){

	type = (Class) sPrimitiveTypes.get(typeWriter.toString());
	if (type == null)
		try {
			if ( fClassLoader == null ) {
				type = Class.forName(typeWriter.toString());
			} else {
				type = fClassLoader.loadClass(typeWriter.toString());
			}
		} catch ( ClassNotFoundException exc ) {
			try {
				type = Class.forName("java.lang." + typeWriter.toString()); //$NON-NLS-1$
				StringWriter writer = new StringWriter();
				writer.write(type.getName());
				typeWriter = writer;
			} catch ( ClassNotFoundException exc1 ) {}
		} catch ( NoClassDefFoundError exc ) {
			// A mismatch in some way. Found a class, probably different case. One possibility
			// is found a class, but this was really a package. So class and package with same name
			// but different case caused this to occur. [46376].
		}
	
}
/**
 * If we have any static methods return the result of evaluating them against the type
 */
public Object evaluate() {

	// If we are an array but haven't created it do so
	if ( isArray() ) {
		if ( array == null ) {
			evaluateArray();
		}
		return array;
	} else {
		if ( type != null ) { 
			return type;
		} else { 
			// If we have no type then we are some kind incomplete expression that cannot be evaluted
			throw new RuntimeException();
		}
	}
}
/**
 * The type of us is either simply the class, or if we are an array then we must create the java.lang.reflect.Array
 * using the reflective APIs
 */
protected Object array;
public Class getTypeClass() {

	if ( isArray() ) {
		if ( array == null ) {
			// Do not evaluate the array and return its class.  Instead just work out the class by our type
			// and number of dimensions
			Object result = Array.newInstance(type,getNumberOfDimensions());
			return result.getClass();
		} else { 
			return array.getClass();
		}
	} else { 
		return type;
	}
}

protected String getTypeClassName() {
	return typeWriter.toString();
}
public Class getPrimitiveTypeClass(){
	return type;
}
protected int[] getNumberOfDimensions(){
	List dimensions = new ArrayList(1);
	dimensions.add(new Integer(fArrayArguments.size()));
	((MessageArgument)fArrayArguments.get(0)).contributeArgumentNumber(dimensions);
	// The total number of arguments is a set of Integer objects in the dimensions list
	// convert this to an int[]
	int[] intDimensions = new int[dimensions.size()];
	for (int i = 0; i < dimensions.size(); i++) {
		intDimensions[i] = ((Integer)dimensions.get(i)).intValue();
	}
	return intDimensions;
}
/**
 * Evaluate the array
 */
protected void evaluateArray(){
	if ( fArrayArguments != null ) { 
		// If the array isn't declared with a size but this is supplied with argument these will be in the fArrayArguments
		// new int[] { 2 ,3 } will have the constructor arguments supplied as two message arguments with 
		if ( array == null ) {
			// The size of the array arguments is our array size, however for a multi arg array we need
			// to find the size of any nested arrays within arguments themselves, e.g. 
			// new int[][] { {2,3} , {3,4} } then we have two array arguments, each of which is a MessageArgument
			// whose statement is an ArrayArguments that has two arguments, etc...
			// To find the number of arguments we create a list that we add our number of arguments to, and then
			// pass this all the way up the arguments chain using contributeArgumentNumber(List) so that each element
			// can add to the list the number of arguments ( if any ) that they have.  
			array = Array.newInstance(type,getNumberOfDimensions());
			// Set the elements in the array to be the result of evaluating the constructor arguments
			for (int i = 0; i < fArrayArguments.size(); i++) {
				Expression expression = (Expression)fArrayArguments.get(i);
				try {	
					Object element = expression.evaluate();
					Array.set(array,i,element);
				} catch ( Exception exc ) {
					// Any evaluation exceptions should be thrown back
					throw new RuntimeException();
				}
			}
		}
	} else if ( arrayDimensions != null ) {
		// To get the class of a reflective array we must actually first create it and then ask it for its class
		// The array Dimensions are present if the array was explicitly declared with a size, e.g. new int[2][3]
		// will have to arrayDimensions that represent the expressions 2 and 3 ( as NumberLiteral instances )
		if ( array == null ) {
			// Evaluate all of the arrayDimensions.  These should be integers
			int[] dimensionSizes = new int[arrayDimensions.size()];
			for (int i = 0; i < dimensionSizes.length; i++) {
				try { 
					Integer dimensionSize = (Integer) ((Expression)arrayDimensions.get(i)).evaluate();
					dimensionSizes[i] = dimensionSize.intValue();
				} catch ( Exception exc ) {
					throw new RuntimeException();
				}
			}
			// For a multi arg array we need to create using the static method on array that takes an int[] that represents
			// the number of dimensions, e.g. for new String[2][3] we do Array.newInstance(String.class,new int[] { 2 , 3 };
			array = Array.newInstance(type,dimensionSizes);
		}
	}
}
/**
 * If the token is a period then it could either be part of the type or else a static method call
 */
public Expression push(char[] token , char delimiter ) {

	// If we don't yet have a valid type then see if we now do
	if (type == null){
		try { 
			typeWriter.write(token);
		} catch ( IOException exc ) {};
		checkForValidType();
		// If we got a valid type and a period then remember it
		if ( delimiter == DelimiterPeriod ) {
			if (type != null) {
				completedWithPeriod = true;
				return this;
			}
		}		
	}
	
	if ( arrayDimensions != null && isProcessingArrayDimension ) {
		Expression lastArrayDimension = (Expression)arrayDimensions.get(arrayDimensions.size()-1);
		lastArrayDimension.push(token,delimiter);
		if ( delimiter == DelimiterCloseSquareBrace && isProcessingArrayDimension ) {
			isProcessingArrayDimension = false;
		}
		return this;
	}
	
	if ( delimiter == DelimiterOpenSquareBrace && !isProcessingArrayDimension ) {
		if ( arrayDimensions == null ) arrayDimensions = new ArrayList(1);
		Statement statement = new Statement(fClassLoader);
		arrayDimensions.add(statement);
		isProcessingArrayDimension = true;
		return this;		
	}
	
	// If we have a type and the delimiter is a ( then it must be a message beginning
	if ( type != null ) {
		if (delimiter == DelimiterOpenParen) {
			isComplete = true;
			return new Message( this , token , fClassLoader );
		} else if (completedWithPeriod){
			isComplete = true;
			Field field = new Field(this,token,fClassLoader);
			// If our token is a ), ' ' or , then the field is completed,
			// otherwise leave it open so it will process the remaining tokens
//			if (delimiter == DelimiterCloseParen || delimiter == DelimiterSpace || delimiter == DelimiterComma) {
			if (delimiter == DelimiterCloseParen || delimiter == DelimiterComma) {
				field.isComplete = true;
			}
			return field;
		}
	}
			
	// We are still looking for a type so append a .
	if ( type == null ) {
		typeWriter.write('.');
	}
	return this;
}
public String toString(){

	StringWriter writer = new StringWriter();
	writer.write("Static "); //$NON-NLS-1$
	if ( type == null ) { 
		writer.write("(Incomplete) {"); //$NON-NLS-1$
	} else {
		writer.write("(Complete) {"); //$NON-NLS-1$
	}
	writer.write(typeWriter.toString());
	writer.write("}"); //$NON-NLS-1$
	if ( arrayDimensions != null ) {
		writer.write(" array dimensions="); //$NON-NLS-1$
		writer.write(new Integer(arrayDimensions.size()).toString());
	}
	if ( fArrayArguments != null ) {	
		writer.write(" array dimensions="); //$NON-NLS-1$
		writer.write(new Integer(fArrayArguments.size()).toString());
	}
	return writer.toString();

}

public boolean isPrimitive() {
	return getTypeClass().isPrimitive();
}
public void setArrayArguments(List arguments) {
	fArrayArguments = arguments;
}
}
