cdc.mf.model.MfOperation Maven / Gradle / Ivy
package cdc.mf.model;
import java.util.Objects;
import cdc.args.Strictness;
import cdc.mf.model.MfElementFeatures.Feature;
import cdc.util.lang.Introspection;
/**
* Operation class.
*
* @author Damien Carbonne
*/
public final class MfOperation extends MfMember
implements MfParameterOwner, MfAbstractItem {
public static final Class PARENT_CLASS =
MfMemberOwner.class;
public static final Class> BUILDER_CLASS =
Introspection.uncheckedCast(Builder.class);
public static final MfElementFeatures FEATURES =
MfElementFeatures.builder()
.feature(Feature.REQUIRES_NAME)
.build();
private final boolean isAbstract;
MfOperation(Builder extends MfMemberOwner> builder) {
super(builder,
FEATURES);
this.isAbstract = builder.isAbstract;
addToParent(FEATURES);
addToModel();
}
@Override
public MfOperation duplicate(MfMemberOwner tgtParent) {
return tgtParent.operation()
.set(this)
.build();
}
@Override
public boolean isAbstract() {
return isAbstract;
}
/**
* @return A String representing the signature of this operation.
* It includes the operation name and parameters types.
* Return type and parameters names are ignored.
*/
public String getSignature() {
final StringBuilder builder = new StringBuilder();
builder.append(getName());
builder.append('(');
boolean first = true;
for (final MfParameter param : getParameters()) {
if (first) {
first = false;
} else {
builder.append(',');
}
builder.append(param.getTypeRef().get().getQName());
}
builder.append(')');
return builder.toString();
}
/**
* @return {@code true} if this operation overrides an inherited one.
* This can be the case if this operation belongs to a type.
*/
public boolean overrides() {
final MfMemberOwner parent = getParent();
if (parent instanceof final MfType parentType) {
// This operation belongs to a type
final String sig = getSignature();
// Iterate on all (strict) ancestors of the parent type
for (final MfType ancestor : parentType.getAllAncestors(Strictness.STRICT)) {
for (final MfOperation op : ancestor.getOperations()) {
if (Objects.equals(sig, op.getSignature())) {
// Found an operation with the same signature
return true;
}
}
}
}
return false;
}
@Override
public MfDocumentation.Builder documentation() {
return MfDocumentation.builder(this);
}
@Override
public MfTag.Builder tag() {
return MfTag.builder(this);
}
@Override
public MfDependency.Builder dependency() {
return MfDependency.builder(this);
}
@Override
public MfParameter.Builder parameter() {
return MfParameter.builder(this);
}
static Builder
builder(P parent) {
return new Builder<>(parent);
}
/**
* Builder of operations.
*
* @author Damien Carbonne
*
* @param
The concrete parent type.
*/
public static final class Builder
extends MfMember.Builder, MfOperation, P> {
private boolean isAbstract = false;
protected Builder(P parent) {
super(parent);
}
@Override
public Builder set(MfOperation element) {
return super.set(element).isAbstract(element.isAbstract());
}
@Override
public Class getElementClass() {
return MfOperation.class;
}
public boolean isAbstract() {
return isAbstract;
}
public Builder isAbstract(boolean isAbstract) {
this.isAbstract = isAbstract;
return self();
}
@Override
public MfOperation build() {
return new MfOperation(this);
}
}
}