xy.reflect.ui.info.type.iterable.map.StandardMapEntryTypeInfo Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (C) 2018 OTK Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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. See the
* GNU General Public License for more details.
*
* The GNU General Public License allows you also to freely redistribute
* the libraries under the same license, if you provide the terms of the
* GNU General Public License with them and add the following
* copyright notice at the appropriate place (with a link to
* http://javacollection.net/reflectionui/ web site when possible).
******************************************************************************/
package xy.reflect.ui.info.type.iterable.map;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import xy.reflect.ui.ReflectionUI;
import xy.reflect.ui.info.field.GetterFieldInfo;
import xy.reflect.ui.info.field.IFieldInfo;
import xy.reflect.ui.info.method.DefaultConstructorInfo;
import xy.reflect.ui.info.method.IMethodInfo;
import xy.reflect.ui.info.parameter.IParameterInfo;
import xy.reflect.ui.info.parameter.ParameterInfoProxy;
import xy.reflect.ui.info.type.DefaultTypeInfo;
import xy.reflect.ui.info.type.ITypeInfo;
import xy.reflect.ui.info.type.source.JavaTypeInfoSource;
import xy.reflect.ui.info.type.source.PrecomputedTypeInfoSource;
import xy.reflect.ui.info.type.source.SpecificitiesIdentifier;
import xy.reflect.ui.info.type.source.TypeInfoSourceProxy;
import xy.reflect.ui.util.ReflectionUIError;
public class StandardMapEntryTypeInfo extends DefaultTypeInfo implements IMapEntryTypeInfo {
protected Class keyJavaType;
protected Class valueJavaType;
protected GetterFieldInfo keyField;
protected GetterFieldInfo valueField;
public StandardMapEntryTypeInfo(ReflectionUI reflectionUI, Class keyJavaType, Class valueJavaType) {
super(reflectionUI, new JavaTypeInfoSource(StandardMapEntry.class, null));
this.keyJavaType = keyJavaType;
this.valueJavaType = valueJavaType;
}
public static boolean isCompatibleWith(Class javaType) {
return javaType.equals(StandardMapEntry.class);
}
@Override
public String getName() {
String keyTypeName = (keyJavaType == null) ? Object.class.getName() : keyJavaType.getName();
String valueTypeName = (valueJavaType == null) ? Object.class.getName() : valueJavaType.getName();
return StandardMapEntry.class.getName() + "<" + keyTypeName + "," + valueTypeName + ">";
}
@Override
public String getCaption() {
return "Entry";
}
@Override
public boolean supportsInstance(Object object) {
if (!super.supportsInstance(object)) {
return false;
}
@SuppressWarnings("rawtypes")
StandardMapEntry entry = (StandardMapEntry) object;
if (entry != null) {
Object key = entry.getKey();
if (key != null) {
if (keyJavaType != null) {
if (!keyJavaType.isInstance(key)) {
return false;
}
}
}
Object value = entry.getValue();
if (value != null) {
if (valueJavaType != null) {
if (!valueJavaType.isInstance(value)) {
return false;
}
}
}
}
return true;
}
@Override
public IFieldInfo getKeyField() {
if (keyField == null) {
try {
keyField = new GetterFieldInfo(reflectionUI,
StandardMapEntry.class.getMethod("getKey", new Class[0]), StandardMapEntry.class) {
ITypeInfo type;
@Override
public ITypeInfo getType() {
if (type == null) {
SpecificitiesIdentifier specificitiesIdentifier = new SpecificitiesIdentifier(
StandardMapEntryTypeInfo.this.getName(), ((IFieldInfo) this).getName());
if (keyJavaType == null) {
type = reflectionUI
.getTypeInfo(new JavaTypeInfoSource(Object.class, specificitiesIdentifier));
} else {
type = reflectionUI
.getTypeInfo(new JavaTypeInfoSource(keyJavaType, specificitiesIdentifier));
}
}
return type;
}
};
} catch (SecurityException e) {
throw new ReflectionUIError(e);
} catch (NoSuchMethodException e) {
throw new ReflectionUIError(e);
}
}
return keyField;
}
@Override
public IFieldInfo getValueField() {
if (valueField == null) {
try {
valueField = new GetterFieldInfo(reflectionUI,
StandardMapEntry.class.getMethod("getValue", new Class[0]), StandardMapEntry.class) {
ITypeInfo type;
@Override
public ITypeInfo getType() {
if (type == null) {
SpecificitiesIdentifier specificitiesIdentifier = new SpecificitiesIdentifier(
StandardMapEntryTypeInfo.this.getName(), ((IFieldInfo) this).getName());
if (valueJavaType == null) {
type = reflectionUI
.getTypeInfo(new JavaTypeInfoSource(Object.class, specificitiesIdentifier));
} else {
type = reflectionUI
.getTypeInfo(new JavaTypeInfoSource(valueJavaType, specificitiesIdentifier));
}
}
return type;
}
};
} catch (SecurityException e) {
throw new ReflectionUIError(e);
} catch (NoSuchMethodException e) {
throw new ReflectionUIError(e);
}
}
return valueField;
}
@Override
public List getFields() {
List result = new ArrayList();
result.add(getKeyField());
result.add(getValueField());
return result;
}
@Override
public List getMethods() {
return Collections.emptyList();
}
@Override
public List getConstructors() {
List result = new ArrayList();
try {
result.add(new StandardMapEntryConstructorInfo());
} catch (Exception e) {
throw new ReflectionUIError(e);
}
return result;
}
protected Constructor getStandardMapEntryjavaConstructor() {
try {
return StandardMapEntry.class.getConstructor(Object.class, Object.class);
} catch (Exception e) {
throw new ReflectionUIError(e);
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((keyJavaType == null) ? 0 : keyJavaType.hashCode());
result = prime * result + ((valueJavaType == null) ? 0 : valueJavaType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
StandardMapEntryTypeInfo other = (StandardMapEntryTypeInfo) obj;
if (keyJavaType == null) {
if (other.keyJavaType != null)
return false;
} else if (!keyJavaType.equals(other.keyJavaType))
return false;
if (valueJavaType == null) {
if (other.valueJavaType != null)
return false;
} else if (!valueJavaType.equals(other.valueJavaType))
return false;
return true;
}
@Override
public String toString() {
return "StandardMapEntryTypeInfo [keyJavaType=" + keyJavaType + ", valueJavaType=" + valueJavaType + "]";
}
protected class StandardMapEntryConstructorInfo extends DefaultConstructorInfo {
public StandardMapEntryConstructorInfo() {
super(StandardMapEntryTypeInfo.this.reflectionUI, getStandardMapEntryjavaConstructor());
}
@Override
public ITypeInfo getReturnValueType() {
return reflectionUI.getTypeInfo(new PrecomputedTypeInfoSource(StandardMapEntryTypeInfo.this, null));
}
@Override
public List getParameters() {
List result = new ArrayList();
for (IParameterInfo param : super.getParameters()) {
result.add(new ParameterInfoProxy(param) {
IFieldInfo relatedField;
{
if (getPosition() == 0) {
relatedField = getKeyField();
} else if (getPosition() == 1) {
relatedField = getValueField();
} else {
throw new ReflectionUIError();
}
}
ITypeInfo type;
@Override
public String getName() {
return relatedField.getName();
}
@Override
public String getCaption() {
return relatedField.getCaption();
}
@Override
public ITypeInfo getType() {
if (type == null) {
type = reflectionUI
.getTypeInfo(new TypeInfoSourceProxy(relatedField.getType().getSource()) {
@Override
public SpecificitiesIdentifier getSpecificitiesIdentifier() {
return null;
}
});
}
return type;
}
@Override
public boolean isNullValueDistinct() {
return relatedField.isNullValueDistinct();
}
});
}
return result;
}
}
}