/
DescribableAttribute.java
83 lines (65 loc) · 2.82 KB
/
DescribableAttribute.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package io.jenkins.plugins.casc.impl.attributes;
import hudson.model.Describable;
import hudson.model.Descriptor;
import io.jenkins.plugins.casc.Attribute;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import jenkins.model.Jenkins;
import org.jenkinsci.Symbol;
import static io.jenkins.plugins.casc.Configurator.normalize;
/**
* @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
*/
public class DescribableAttribute<Owner, Type> extends Attribute<Owner, Type> {
public DescribableAttribute(String name, Class<? extends Describable> type) {
super(name, type);
}
@Override
public List<String> possibleValues() {
final List<Descriptor> descriptors = Jenkins.get().getDescriptorList(type);
return descriptors.stream()
.map(d -> getPreferredSymbol(d, type, d.getKlass().toJavaClass()))
.collect(Collectors.toList());
}
/**
* Retrieve the preferred symbol for this descriptor
*/
public static String getPreferredSymbol(Descriptor d, Class extensionPoint, Class target) {
return getSymbols(d, extensionPoint, target).get(0);
}
/**
* Retrieve all possible symbols for this descriptor, first one being preferred one.
* If a {@link Symbol} annotation is set, all values are accepted the last one being preferred
*/
public static List<String> getSymbols(Descriptor d, Class extensionPoint, Class target) {
if (d != null) {
List<String> symbols = new ArrayList<>();
// explicit @Symbol annotation on descriptor
// first is the preferred one as by Symbol contract
// "The first one is used as the primary identifier for reverse-mapping."
Symbol s = d.getClass().getAnnotation(Symbol.class);
if (s != null) {
symbols.addAll(Arrays.asList(s.value()));
}
// extension type Foo is implemented as SomeFoo. => "some"
final String ext = extensionPoint.getSimpleName();
final String cn = d.getKlass().toJavaClass().getSimpleName();
if (cn.endsWith(ext)) {
symbols.add( normalize(cn.substring(0, cn.length() - ext.length())) );
}
// extension type Foo is implemented as SomeFooImpl. => "some"
final String in = extensionPoint.getSimpleName() + "Impl";
if (cn.endsWith(in)) {
symbols.add( normalize(cn.substring(0, cn.length() - in.length())) );
}
// Fall back to simple class name
symbols.add( normalize(cn) );
return symbols;
}
// Fall back to simple class name
return Collections.singletonList(normalize(target.getSimpleName()));
}
}