/*********************************************************************************
* TotalCross Software Development Kit *
* Copyright (C) 1998, 1999 Wabasoft <www.wabasoft.com> *
* Copyright (C) 2000-2012 SuperWaba Ltda. *
* All Rights Reserved *
* *
* This library and virtual machine is distributed in the hope that it will *
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 *
* A copy of this license is located in file license.txt at the root of this *
* SDK or can be downloaded here: *
* http://www.gnu.org/licenses/lgpl-3.0.txt *
* *
*********************************************************************************/
package totalcross.lang;
import java.lang.reflect.*;
/**
* This class contains utility methods that are used to load classes by name
* and get information about their fields and methods.
* <br><br>
* IMPORTANT: the totalcross.lang package is the java.lang that will be used in the device.
* You CANNOT use nor import totalcross.lang package in desktop. When tc.Deploy is called,
* all references to java.lang are replaced by totalcross.lang automatically. Given this,
* you must use only the classes and methods that exists BOTH in java.lang and totalcross.lang.
* For example, you can't use java.lang.ClassLoader because there are no totalcross.lang.ClassLoader.
* Another example, you can't use java.lang.String.indexOfIgnoreCase because there are no
* totalcross.lang.String.indexOfIgnoreCase method. Trying to use a class or method from the java.lang package
* that has no correspondence with totalcross.lang will make the tc.Deploy program to abort, informing
* where the problem occured. A good idea is to always refer to this javadoc to know what is and what isn't
* available.
*/
public final class Class4D<T>
{
// place holders for the VM
Object nativeStruct; // TClass
String targetName; // java.lang.String
String ncached,cached;
/** The TotalCross deployer can find classes that are instantiated using Class.forName if, and only if, they are
* String constants. If you build the className dynamically, then you must include the file passing it to the tc.Deploy
* application (the deployer will warn you about that).
* @see totalcross.sys.Vm#attachLibrary
*/
native public static Class<?> forName(String className) throws java.lang.ClassNotFoundException;
/** Creates a new instance of this class. The class must have a default and public constructor (E.G.: <code>public MyClass()</code>)
* @throws InstantiationException If you try to instantiate an interface, abstract class or array
* @throws IllegalAccessException If you try to instantiate a private class
*/
native public Object newInstance() throws java.lang.InstantiationException, java.lang.IllegalAccessException;
/** Returns true if the given object is an instance of this class. */
native public boolean isInstance(Object obj);
/** Returns the fully qualified name of this class. */
public String getName()
{
if (ncached != null) return ncached;
if (isPrimitive())
{
if (targetName.endsWith(".Integer")) return "int";
if (targetName.endsWith(".Character")) return "char";
if (targetName.endsWith(".Byte")) return "byte";
if (targetName.endsWith(".Short")) return "short";
if (targetName.endsWith(".Long")) return "long";
if (targetName.endsWith(".Float")) return "float";
if (targetName.endsWith(".Double")) return "double";
if (targetName.endsWith(".Boolean")) return "boolean";
}
return ncached = targetName;
}
/** Returns the fully qualified name of this class. */
public String toString()
{
if (cached != null) return cached;
return cached = isPrimitive() ? getName() : "class "+getName();
}
public boolean equals(Object o)
{
return o instanceof Class4D && ((Class4D)o).getName().equals(getName());
}
/**
* Returns the enumeration constants of this class, or
* null if this class is not an <code>Enum</code>.
*
* @return an array of <code>Enum</code> constants
* associated with this class, or null if this
* class is not an <code>enum</code>.
* @since 1.5
*/
public T[] getEnumConstants()
{
try
{
Method m = getMethod("values", new Class[0]);
return (T[]) m.invoke(null, new Object[0]);
}
catch (NoSuchMethodException exception)
{
throw new Error("Enum lacks values() method");
}
catch (IllegalAccessException exception)
{
throw new Error("Unable to access Enum class");
}
catch (InvocationTargetException exception)
{
throw new
RuntimeException("The values method threw an exception",
exception);
}
}
public String getSimpleName()
{
String s = getName();
return s.substring(s.lastIndexOf('.')+1);
}
public native boolean isAssignableFrom(Class<?> cls);
public native boolean isInterface();
public native boolean isArray();
public native boolean isPrimitive();
public native Class<?> getSuperclass();
public native Class<?>[] getInterfaces();
public native Class<?> getComponentType();
public native int getModifiers();
public native Object[] getSigners();
public native Field[] getFields() throws SecurityException;
public native Method[] getMethods() throws SecurityException;
public native Constructor<?>[] getConstructors() throws SecurityException;
public native Field getField(String name) throws NoSuchFieldException, SecurityException;
public native Method getMethod(String name, Class<?> parameterTypes[]) throws NoSuchMethodException, SecurityException;
public native Constructor<?> getConstructor(Class<?> parameterTypes[]) throws NoSuchMethodException, SecurityException;
public native Field[] getDeclaredFields() throws SecurityException;
public native Method[] getDeclaredMethods() throws SecurityException;
public native Constructor<?>[] getDeclaredConstructors() throws SecurityException;
public native Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException;
public native Method getDeclaredMethod(String name, Class<?> parameterTypes[]) throws NoSuchMethodException, SecurityException;
public native Constructor<?> getDeclaredConstructor(Class<?> parameterTypes[]) throws NoSuchMethodException, SecurityException;
}