/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.target;
import java.util.List;
import java.util.Set;
import com.opengamma.id.UniqueIdentifiable;
/**
* A computation target that can be of a single Java type.
*/
/* package */final class ClassComputationTargetType extends ComputationTargetType {
private static final long serialVersionUID = 1L;
private final Class<? extends UniqueIdentifiable> _target;
/**
* Display/legacy name of the target type. This is not part of the equality or hash.
*/
private final String _name;
/**
* Flag to use the display/legacy name as the formal string.
*/
private final boolean _nameWellKnown;
/**
* Creates a new instance.
*
* @param target the target class
* @param name the preferred display name for the type, this must not contain {@code ()/|} characters
*/
public ClassComputationTargetType(final Class<? extends UniqueIdentifiable> target, final String name, final boolean nameWellKnown) {
//ok to use concrete class rather than getClass() since this class is final
super(ClassComputationTargetType.class.getName().hashCode() * 31 + target.getName().hashCode());
_target = target;
_name = name;
_nameWellKnown = nameWellKnown;
}
protected Class<? extends UniqueIdentifiable> getTarget() {
return _target;
}
@Override
public String getName() {
return _name;
}
protected boolean isNameWellKnown() {
return _nameWellKnown;
}
@Override
public boolean isCompatible(final UniqueIdentifiable target) {
return (target != null) && isCompatible(target.getClass());
}
@Override
public boolean isCompatible(final Class<? extends UniqueIdentifiable> clazz) {
return getTarget().isAssignableFrom(clazz);
}
private static final ComputationTargetTypeVisitor<ClassComputationTargetType, Boolean> s_isCompatible = new ComputationTargetTypeVisitor<ClassComputationTargetType, Boolean>() {
@Override
public Boolean visitMultipleComputationTargetTypes(final Set<ComputationTargetType> types, final ClassComputationTargetType self) {
for (ComputationTargetType type : types) {
if (self.isCompatible(type)) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
@Override
public Boolean visitNestedComputationTargetTypes(final List<ComputationTargetType> types, final ClassComputationTargetType self) {
return self.isCompatible(types.get(types.size() - 1));
}
@Override
public Boolean visitNullComputationTargetType(final ClassComputationTargetType self) {
return Boolean.FALSE;
}
@Override
public Boolean visitClassComputationTargetType(final Class<? extends UniqueIdentifiable> type, final ClassComputationTargetType self) {
return self.getTarget().isAssignableFrom(type);
}
};
@Override
public boolean isCompatible(final ComputationTargetType type) {
return type.accept(s_isCompatible, this);
}
private static final ComputationTargetTypeVisitor<ClassComputationTargetType, Boolean> s_isTargetType = new ComputationTargetTypeVisitor<ClassComputationTargetType, Boolean>() {
@Override
public Boolean visitMultipleComputationTargetTypes(final Set<ComputationTargetType> types, final ClassComputationTargetType self) {
for (ComputationTargetType type : types) {
if (self.isTargetType(type)) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
@Override
public Boolean visitNestedComputationTargetTypes(final List<ComputationTargetType> types, final ClassComputationTargetType self) {
return Boolean.FALSE;
}
@Override
public Boolean visitNullComputationTargetType(final ClassComputationTargetType self) {
return Boolean.FALSE;
}
@Override
public Boolean visitClassComputationTargetType(final Class<? extends UniqueIdentifiable> type, final ClassComputationTargetType self) {
return self.isTargetType(type);
}
};
@Override
public boolean isTargetType(final ComputationTargetType type) {
return type.accept(s_isTargetType, this);
}
@Override
public boolean isTargetType(final Class<? extends UniqueIdentifiable> type) {
return type.isAssignableFrom(getTarget());
}
@Override
public <D, T> T accept(final ComputationTargetTypeVisitor<D, T> visitor, final D data) {
return visitor.visitClassComputationTargetType(getTarget(), data);
}
@Override
public String toString() {
return isNameWellKnown() ? getName() : getTarget().getName();
}
@Override
protected void toStringNested(final StringBuilder sb) {
sb.append(toString());
}
@Override
protected void getNameNested(final StringBuilder sb) {
sb.append(getName());
}
private static final ComputationTargetTypeVisitor<ClassComputationTargetType, Boolean> s_equals = new ComputationTargetTypeVisitor<ClassComputationTargetType, Boolean>() {
@Override
public Boolean visitMultipleComputationTargetTypes(final Set<ComputationTargetType> types, final ClassComputationTargetType self) {
return Boolean.FALSE;
}
@Override
public Boolean visitNestedComputationTargetTypes(final List<ComputationTargetType> types, final ClassComputationTargetType self) {
return Boolean.FALSE;
}
@Override
public Boolean visitNullComputationTargetType(final ClassComputationTargetType self) {
return Boolean.FALSE;
}
@Override
public Boolean visitClassComputationTargetType(final Class<? extends UniqueIdentifiable> type, final ClassComputationTargetType self) {
return self.getTarget().equals(type);
}
};
@Override
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (o instanceof ComputationTargetType) {
return ((ComputationTargetType) o).accept(s_equals, this).booleanValue();
} else {
return false;
}
}
}