All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xy.reflect.ui.info.type.DefaultTypeInfo Maven / Gradle / Ivy

package xy.reflect.ui.info.type;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import xy.reflect.ui.ReflectionUI;
import xy.reflect.ui.info.AbstractInfo;
import xy.reflect.ui.info.ResourcePath;
import xy.reflect.ui.info.field.GetterFieldInfo;
import xy.reflect.ui.info.field.IFieldInfo;
import xy.reflect.ui.info.field.PublicFieldInfo;
import xy.reflect.ui.info.menu.MenuModel;
import xy.reflect.ui.info.method.AbstractConstructorInfo;
import xy.reflect.ui.info.method.DefaultConstructorInfo;
import xy.reflect.ui.info.method.DefaultMethodInfo;
import xy.reflect.ui.info.method.IMethodInfo;
import xy.reflect.ui.info.method.InvocationData;
import xy.reflect.ui.info.parameter.IParameterInfo;
import xy.reflect.ui.info.type.source.PrecomputedTypeInfoSource;
import xy.reflect.ui.util.ClassUtils;
import xy.reflect.ui.util.ReflectionUIError;
import xy.reflect.ui.util.ReflectionUIUtils;

public class DefaultTypeInfo extends AbstractInfo implements ITypeInfo {

	protected Class javaType;
	protected ReflectionUI reflectionUI;
	protected List fields;
	protected List methods;
	protected List constructors;

	public DefaultTypeInfo(ReflectionUI reflectionUI, Class javaType) {
		if (javaType == null) {
			throw new ReflectionUIError();
		}
		this.reflectionUI = reflectionUI;
		this.javaType = javaType;
	}

	public Class getJavaType() {
		return javaType;
	}

	@Override
	public boolean canPersist() {
		return true;
	}

	@Override
	public void save(Object object, OutputStream out) {
		ReflectionUIUtils.saveXML(object, out);
	}

	@Override
	public void load(Object object, InputStream in) {
		ReflectionUIUtils.loadXML(object, in);
	}

	@Override
	public FieldsLayout getFieldsLayout() {
		return FieldsLayout.VERTICAL_FLOW;
	}

	@Override
	public MenuModel getMenuModel() {
		return new MenuModel();
	}

	@Override
	public boolean isPrimitive() {
		return javaType.isPrimitive();
	}

	@Override
	public boolean isImmutable() {
		return ClassUtils.isKnownAsImmutableClass(javaType);
	}

	@Override
	public boolean isConcrete() {
		if ((!javaType.isPrimitive()) && Modifier.isAbstract(javaType.getModifiers())) {
			return false;
		}
		if (javaType.isInterface()) {
			return false;
		}
		if (javaType == Object.class) {
			return false;
		}
		return true;
	}

	@Override
	public boolean isModificationStackAccessible() {
		return true;
	}

	@Override
	public List getConstructors() {
		if (constructors == null) {
			constructors = new ArrayList();
			if (ClassUtils.isPrimitiveClassOrWrapperOrString(javaType)) {
				constructors.add(new AbstractConstructorInfo() {

					@Override
					public Object invoke(Object object, InvocationData invocationData) {
						if (String.class.equals(javaType)) {
							return "";
						} else {
							Class primitiveType = javaType;
							if (ClassUtils.isPrimitiveWrapperClass(primitiveType)) {
								primitiveType = ClassUtils.wrapperToPrimitiveClass(javaType);
							}
							return ClassUtils.getDefaultPrimitiveValue(primitiveType);
						}
					}

					@Override
					public ITypeInfo getReturnValueType() {
						return reflectionUI.getTypeInfo(new PrecomputedTypeInfoSource(DefaultTypeInfo.this));
					}

					@Override
					public List getParameters() {
						return Collections.emptyList();
					}
				});
			} else {
				for (Constructor javaConstructor : javaType.getConstructors()) {
					if (!DefaultConstructorInfo.isCompatibleWith(javaConstructor)) {
						continue;
					}
					constructors.add(new DefaultConstructorInfo(reflectionUI, javaConstructor));
				}
			}
		}
		return constructors;
	}

	@Override
	public String getName() {
		return javaType.getName();
	}

	@Override
	public String getCaption() {
		if (String.class.equals(javaType)) {
			return "Text";
		} else if (javaType.isPrimitive()) {
			return ClassUtils.primitiveToWrapperClass(javaType).getSimpleName();
		} else {
			return ReflectionUIUtils.identifierToCaption(javaType.getSimpleName());
		}
	}

	@Override
	public List getFields() {
		if (fields == null) {
			fields = new ArrayList();
			for (Field javaField : javaType.getFields()) {
				if (!PublicFieldInfo.isCompatibleWith(javaField)) {
					continue;
				}
				fields.add(new PublicFieldInfo(reflectionUI, javaField, javaType));
			}
			for (Method javaMethod : javaType.getMethods()) {
				if (!GetterFieldInfo.isCompatibleWith(javaMethod, javaType)) {
					continue;
				}
				GetterFieldInfo getterFieldInfo = new GetterFieldInfo(reflectionUI, javaMethod, javaType);
				fields.add(getterFieldInfo);
			}
			ReflectionUIUtils.sortFields(fields);
		}
		return fields;
	}

	@Override
	public List getMethods() {
		if (methods == null) {
			methods = new ArrayList();
			for (Method javaMethod : javaType.getMethods()) {
				if (!DefaultMethodInfo.isCompatibleWith(javaMethod, javaType)) {
					continue;
				}
				methods.add(new DefaultMethodInfo(reflectionUI, javaMethod));
			}
			ReflectionUIUtils.sortMethods(methods);
		}
		return methods;
	}

	@Override
	public boolean supportsInstance(Object object) {
		if (javaType.isPrimitive()) {
			return ClassUtils.primitiveToWrapperClass(javaType).isInstance(object);
		} else {
			return javaType.isInstance(object);
		}
	}

	@Override
	public List getPolymorphicInstanceSubTypes() {
		return Collections.emptyList();
	}

	@Override
	public String toString(Object object) {
		ReflectionUIUtils.checkInstance(this, object);
		if (object == null) {
			return null;
		} else if (object instanceof String) {
			return (String) object;
		} else {
			String result = object.toString();
			if (result == null) {
				result = "";
			}
			result = result.replaceAll(
					javaType.getName().replace(".", "\\.").replace("$", "\\$").replace("[", "\\[") + "@([0-9a-z]+)",
					getCaption() + " [id=$1]");
			result = result.replace(javaType.getName(), getCaption());
			return result;
		}
	}

	@Override
	public ResourcePath getIconImagePath() {
		return null;
	}

	@Override
	public String getOnlineHelp() {
		return null;
	}

	@Override
	public void validate(Object object) throws Exception {
		ReflectionUIUtils.checkInstance(this, object);
	}

	@Override
	public Map getSpecificProperties() {
		return Collections.emptyMap();
	}

	@Override
	public boolean canCopy(Object object) {
		ReflectionUIUtils.checkInstance(this, object);
		if (object == null) {
			return true;
		}
		if (object instanceof Serializable) {
			return true;
		}
		return false;
	}

	@Override
	public Object copy(Object object) {
		ReflectionUIUtils.checkInstance(this, object);
		if (object == null) {
			return null;
		}
		return ReflectionUIUtils.copyThroughSerialization((Serializable) object);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((javaType == null) ? 0 : javaType.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		DefaultTypeInfo other = (DefaultTypeInfo) obj;
		if (javaType == null) {
			if (other.javaType != null)
				return false;
		} else if (!javaType.equals(other.javaType))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "DefaultTypeInfo [javaType=" + javaType + "]";
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy