Skip to content
Permalink
Browse files

[JENKINS-43507] Remove gratuitous use of generics in the SPI

Since every implementation needs to cast anyway, the generics signature was unnecessary.

We could use generics at the class level to provide type safety, except that would basically force 5 or 6 generic type parameters which gets very ridicluous.

Instead we just provide the guarantee that casting is always pre-checked and safe
  • Loading branch information...
stephenc committed May 8, 2017
1 parent f37b494 commit eaa2c04e33572871ac34109ba896ae580b02ebf0
@@ -47,21 +47,23 @@
* @param context the context.
*/
public final void applyToContext(SCMNavigatorContext<?, ?> context) {
if (getDescriptor().isApplicableToContext(context.getClass())) {
SCMNavigatorTraitDescriptor d = getDescriptor();
if (d.getContextClass().isInstance(context) && d.isApplicableToContext(context.getClass())) {
// guard against non-applicable
decorateContext((SCMNavigatorContext) context);
decorateContext(context);
}
}

/**
* SPI: Override this method to decorate a {@link SCMNavigatorContext}. You can assume that your
* {@link SCMNavigatorTraitDescriptor#isApplicableToContext(Class)} is {@code true} within this method.
* {@link SCMNavigatorTraitDescriptor#isApplicableToContext(Class)} is {@code true} within this method and that
* the provided context is an instance of {@link SCMNavigatorTraitDescriptor#getContextClass()}.
*
* @param context the context (invariant: {@link SCMNavigatorTraitDescriptor#isApplicableToContext(Class)} is {@code true})
* @param <B> generic type parameter to ensure type information available.
* @param <R> generic type parameter to ensure type information available.
* @param context the context (invariant: {@link SCMNavigatorTraitDescriptor#isApplicableToContext(Class)} is {@code
* true} and {@link SCMNavigatorTraitDescriptor#getContextClass()} {@link Class#isInstance(Object)})
* is {@code true})
*/
protected <B extends SCMNavigatorContext<B, R>, R extends SCMNavigatorRequest> void decorateContext(B context) {
protected void decorateContext(SCMNavigatorContext<?, ?> context) {
}

/**
@@ -92,22 +94,25 @@ protected SCMSourceObserver decorateObserver(@NonNull SCMSourceObserver observer
* @param builder the builder.
*/
public final void applyToBuilder(SCMSourceBuilder<?, ?> builder) {
if (!getDescriptor().isApplicableToBuilder(builder)) {
SCMNavigatorTraitDescriptor d = getDescriptor();
if (d.getBuilderClass().isInstance(builder) && d.isApplicableToBuilder(builder)) {
// guard against non-applicable
decorateBuilder(builder);
}
decorateBuilder((SCMSourceBuilder) builder);
}

/**
* SPI: Override this method to decorate a {@link SCMBuilder}. You can assume that your
* {@link SCMSourceTraitDescriptor#isApplicableToBuilder(SCMBuilder)} is {@code true} within this method.
* {@link SCMNavigatorTraitDescriptor#isApplicableToBuilder(SCMSourceBuilder)} is {@code true} within this method
* and that
* the provided builder is an instance of {@link SCMNavigatorTraitDescriptor#getBuilderClass()}.
*
* @param builder the builder (invariant: {@link SCMSourceTraitDescriptor#isApplicableToBuilder(SCMBuilder)} is
* {@code true})
* @param <B> generic type parameter to ensure type information available.
* @param <S> generic type parameter to ensure type information available.
* @param builder the builder (invariant:
* {@link SCMNavigatorTraitDescriptor#isApplicableToBuilder(SCMSourceBuilder)} is
* {@code true} and {@link SCMNavigatorTraitDescriptor#getBuilderClass()}
* {@link Class#isInstance(Object)}) is {@code true})
*/
protected <B extends SCMSourceBuilder<B, S>, S extends SCMSource> void decorateBuilder(B builder) {
protected void decorateBuilder(SCMSourceBuilder<?, ?> builder) {
}

/**
@@ -24,12 +24,11 @@

package jenkins.scm.api.trait;

import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.DescriptorExtensionList;
import hudson.scm.SCM;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.CheckForNull;
import jenkins.scm.api.SCMHeadCategory;
import jenkins.scm.api.SCMHeadObserver;
import jenkins.scm.api.SCMSource;
@@ -48,22 +47,23 @@
* @param context the context.
*/
public final void applyToContext(SCMSourceContext<?, ?> context) {
if (getDescriptor().isApplicableToContext(context.getClass())) {
SCMSourceTraitDescriptor d = getDescriptor();
if (d.getContextClass().isInstance(context) && d.isApplicableToContext(context.getClass())) {
// guard against non-applicable
decorateContext((SCMSourceContext) context);
decorateContext(context);
}
}

/**
* SPI: Override this method to decorate a {@link SCMSourceContext}. You can assume that your
* {@link SCMSourceTraitDescriptor#isApplicableToContext(Class)} is {@code true} within this method.
* {@link SCMSourceTraitDescriptor#isApplicableToContext(Class)} is {@code true} within this method and that
* the provided context is an instance of {@link SCMSourceTraitDescriptor#getContextClass()}.
*
* @param context the context (invariant: {@link SCMSourceTraitDescriptor#isApplicableToContext(Class)} is {@code
* true})
* @param <B> generic type parameter to ensure type information available.
* @param <R> generic type parameter to ensure type information available.
* true} and {@link SCMSourceTraitDescriptor#getContextClass()} {@link Class#isInstance(Object)})
* is {@code true})
*/
protected <B extends SCMSourceContext<B, R>, R extends SCMSourceRequest> void decorateContext(B context) {
protected void decorateContext(SCMSourceContext<?, ?> context) {
}

/**
@@ -94,22 +94,23 @@ protected SCMHeadObserver decorateObserver(@NonNull SCMHeadObserver observer) {
* @param builder the builder.
*/
public final void applyToBuilder(SCMBuilder<?, ?> builder) {
if (!getDescriptor().isApplicableToBuilder(builder)) {
SCMSourceTraitDescriptor d = getDescriptor();
if (d.getBuilderClass().isInstance(builder) && d.isApplicableToBuilder(builder)) {
// guard against non-applicable
decorateBuilder(builder);
}
decorateBuilder((SCMBuilder) builder);
}

/**
* SPI: Override this method to decorate a {@link SCMBuilder}. You can assume that your
* {@link SCMSourceTraitDescriptor#isApplicableToBuilder(SCMBuilder)} is {@code true} within this method.
* {@link SCMSourceTraitDescriptor#isApplicableToBuilder(SCMBuilder)} is {@code true} within this method and that
* the provided builder is an instance of {@link SCMSourceTraitDescriptor#getBuilderClass()}.
*
* @param builder the builder (invariant: {@link SCMSourceTraitDescriptor#isApplicableToBuilder(SCMBuilder)} is
* {@code true})
* @param <B> generic type parameter to ensure type information available.
* @param <S> generic type parameter to ensure type information available.
* {@code true} and {@link SCMSourceTraitDescriptor#getBuilderClass()}
* {@link Class#isInstance(Object)}) is {@code true})
*/
protected <B extends SCMBuilder<B, S>, S extends SCM> void decorateBuilder(B builder) {
protected void decorateBuilder(SCMBuilder<?, ?> builder) {
}

/**
@@ -157,8 +158,9 @@ public SCMSourceTraitDescriptor getDescriptor() {
* @param builderClass (optional) type of {@link SCMBuilder}.
* @return the list of matching {@link SCMSourceTraitDescriptor} instances.
*/
public static List<SCMSourceTraitDescriptor> _for(Class<? extends SCMSourceContext> contextClass,
Class<? extends SCMBuilder> builderClass) {
public static List<SCMSourceTraitDescriptor> _for(
@CheckForNull Class<? extends SCMSourceContext> contextClass,
@CheckForNull Class<? extends SCMBuilder> builderClass) {
return _for(null, contextClass, builderClass);
}

@@ -171,9 +173,10 @@ public SCMSourceTraitDescriptor getDescriptor() {
* @param builderClass (optional) type of {@link SCMBuilder}.
* @return the list of matching {@link SCMSourceTraitDescriptor} instances.
*/
public static List<SCMSourceTraitDescriptor> _for(@CheckForNull SCMSourceDescriptor scmSource,
@CheckForNull Class<? extends SCMSourceContext> contextClass,
@CheckForNull Class<? extends SCMBuilder> builderClass) {
public static List<SCMSourceTraitDescriptor> _for(
@CheckForNull SCMSourceDescriptor scmSource,
@CheckForNull Class<? extends SCMSourceContext> contextClass,
@CheckForNull Class<? extends SCMBuilder> builderClass) {
List<SCMSourceTraitDescriptor> result = new ArrayList<SCMSourceTraitDescriptor>();
if (scmSource != null) {
for (SCMSourceTraitDescriptor d : all()) {
@@ -34,7 +34,6 @@
import jenkins.scm.api.SCMSource;
import jenkins.scm.api.trait.SCMHeadPrefilter;
import jenkins.scm.api.trait.SCMSourceContext;
import jenkins.scm.api.trait.SCMSourceRequest;
import jenkins.scm.api.trait.SCMSourceTrait;
import jenkins.scm.api.trait.SCMSourceTraitDescriptor;
import org.kohsuke.accmod.Restricted;
@@ -100,7 +99,7 @@ private Pattern getPattern() {
* {@inheritDoc}
*/
@Override
protected <B extends SCMSourceContext<B, R>, R extends SCMSourceRequest> void decorateContext(B context) {
protected void decorateContext(SCMSourceContext<?, ?> context) {
context.withPrefilter(new SCMHeadPrefilter() {
@Override
public boolean isExcluded(@NonNull SCMSource source, @NonNull SCMHead head) {
@@ -32,7 +32,6 @@
import java.util.regex.PatternSyntaxException;
import jenkins.scm.api.SCMNavigator;
import jenkins.scm.api.trait.SCMNavigatorContext;
import jenkins.scm.api.trait.SCMNavigatorRequest;
import jenkins.scm.api.trait.SCMNavigatorTrait;
import jenkins.scm.api.trait.SCMNavigatorTraitDescriptor;
import jenkins.scm.api.trait.SCMSourcePrefilter;
@@ -99,7 +98,7 @@ private Pattern getPattern() {
* {@inheritDoc}
*/
@Override
protected <B extends SCMNavigatorContext<B, R>, R extends SCMNavigatorRequest> void decorateContext(B context) {
protected void decorateContext(SCMNavigatorContext<?, ?> context) {
context.withPrefilter(new SCMSourcePrefilter() {
@Override
public boolean isExcluded(@NonNull SCMNavigator source, @NonNull String projectName) {
@@ -32,7 +32,6 @@
import jenkins.scm.api.SCMSource;
import jenkins.scm.api.trait.SCMHeadPrefilter;
import jenkins.scm.api.trait.SCMSourceContext;
import jenkins.scm.api.trait.SCMSourceRequest;
import jenkins.scm.api.trait.SCMSourceTrait;
import jenkins.scm.api.trait.SCMSourceTraitDescriptor;
import org.apache.commons.lang.StringUtils;
@@ -92,7 +91,7 @@ public String getExcludes() {
* {@inheritDoc}
*/
@Override
protected <B extends SCMSourceContext<B, R>, R extends SCMSourceRequest> void decorateContext(B context) {
protected void decorateContext(SCMSourceContext<?, ?> context) {
context.withPrefilter(new SCMHeadPrefilter() {
@Override
public boolean isExcluded(@NonNull SCMSource request, @NonNull SCMHead head) {
@@ -29,7 +29,6 @@
import java.util.regex.Pattern;
import jenkins.scm.api.SCMNavigator;
import jenkins.scm.api.trait.SCMNavigatorContext;
import jenkins.scm.api.trait.SCMNavigatorRequest;
import jenkins.scm.api.trait.SCMNavigatorTrait;
import jenkins.scm.api.trait.SCMNavigatorTraitDescriptor;
import jenkins.scm.api.trait.SCMSourcePrefilter;
@@ -90,7 +89,7 @@ public String getExcludes() {
* {@inheritDoc}
*/
@Override
protected <B extends SCMNavigatorContext<B, R>, R extends SCMNavigatorRequest> void decorateContext(B context) {
protected void decorateContext(SCMNavigatorContext<?, ?> context) {
context.withPrefilter(new SCMSourcePrefilter() {
@Override
public boolean isExcluded(@NonNull SCMNavigator source, @NonNull String projectName) {
@@ -26,9 +26,8 @@

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import jenkins.scm.api.trait.SCMBuilder;
import jenkins.scm.api.SCMHeadCategory;
import jenkins.scm.api.trait.SCMSourceRequest;
import jenkins.scm.api.trait.SCMBuilder;
import jenkins.scm.api.trait.SCMSourceContext;
import jenkins.scm.api.trait.SCMSourceTrait;
import jenkins.scm.api.trait.SCMSourceTraitDescriptor;
@@ -41,10 +40,8 @@ public MockSCMDiscoverBranches() {
}

@Override
protected <B extends SCMSourceContext<B, R>, R extends SCMSourceRequest> void decorateContext(B context) {
if (context instanceof MockSCMSourceContext) {
((MockSCMSourceContext) context).withBranches(true);
}
protected void decorateContext(SCMSourceContext<?, ?> context) {
((MockSCMSourceContext) context).withBranches(true);
}

@Override
@@ -30,11 +30,10 @@
import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;
import jenkins.scm.api.trait.SCMBuilder;
import jenkins.scm.api.SCMHeadCategory;
import jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy;
import jenkins.scm.api.trait.SCMBuilder;
import jenkins.scm.api.trait.SCMSourceContext;
import jenkins.scm.api.trait.SCMSourceRequest;
import jenkins.scm.api.trait.SCMSourceTrait;
import jenkins.scm.api.trait.SCMSourceTraitDescriptor;
import jenkins.scm.impl.ChangeRequestSCMHeadCategory;
@@ -81,11 +80,10 @@ public String getStrategiesStr() {


@Override
protected <B extends SCMSourceContext<B, R>, R extends SCMSourceRequest> void decorateContext(B context) {
if (context instanceof MockSCMSourceContext) {
((MockSCMSourceContext) context).withChangeRequests(true);
((MockSCMSourceContext) context).withCheckoutStrategies(strategies);
}
protected void decorateContext(SCMSourceContext<?, ?> context) {
MockSCMSourceContext ctx = (MockSCMSourceContext) context;
ctx.withChangeRequests(true);
ctx.withCheckoutStrategies(strategies);
}

@Override
@@ -26,10 +26,9 @@

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import jenkins.scm.api.trait.SCMBuilder;
import jenkins.scm.api.SCMHeadCategory;
import jenkins.scm.api.trait.SCMBuilder;
import jenkins.scm.api.trait.SCMSourceContext;
import jenkins.scm.api.trait.SCMSourceRequest;
import jenkins.scm.api.trait.SCMSourceTrait;
import jenkins.scm.api.trait.SCMSourceTraitDescriptor;
import jenkins.scm.impl.TagSCMHeadCategory;
@@ -42,10 +41,8 @@ public MockSCMDiscoverTags() {
}

@Override
protected <B extends SCMSourceContext<B, R>, R extends SCMSourceRequest> void decorateContext(B context) {
if (context instanceof MockSCMSourceContext) {
((MockSCMSourceContext) context).withTags(true);
}
protected void decorateContext(SCMSourceContext<?, ?> context) {
((MockSCMSourceContext) context).withTags(true);
}

@Override

0 comments on commit eaa2c04

Please sign in to comment.
You can’t perform that action at this time.