item) {
return item.getInstance();
}
diff --git a/core/src/main/java/hudson/EnvVars.java b/core/src/main/java/hudson/EnvVars.java
index a323c4d39fa3..cce69ede9ee8 100644
--- a/core/src/main/java/hudson/EnvVars.java
+++ b/core/src/main/java/hudson/EnvVars.java
@@ -1,18 +1,18 @@
/*
* The MIT License
- *
+ *
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Red Hat, Inc.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -21,30 +21,29 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
package hudson;
+import edu.umd.cs.findbugs.annotations.CheckForNull;
+import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.remoting.VirtualChannel;
-import hudson.util.CaseInsensitiveComparator;
import hudson.util.CyclicGraphDetector;
import hudson.util.CyclicGraphDetector.CycleDetectedException;
import hudson.util.VariableResolver;
-import jenkins.security.MasterToSlaveCallable;
-
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-import java.util.Arrays;
import java.util.TreeSet;
import java.util.UUID;
import java.util.logging.Logger;
-import edu.umd.cs.findbugs.annotations.NonNull;
-import edu.umd.cs.findbugs.annotations.CheckForNull;
+import jenkins.security.MasterToSlaveCallable;
/**
* Environment variables.
@@ -65,7 +64,7 @@
*
*
* In Jenkins, often we need to build up "environment variable overrides"
- * on master, then to execute the process on agents. This causes a problem
+ * on the controller, then to execute the process on agents. This causes a problem
* when working with variables like {@code PATH}. So to make this work,
* we introduce a special convention {@code PATH+FOO} — all entries
* that starts with {@code PATH+} are merged and prepended to the inherited
@@ -73,7 +72,7 @@
*
* @author Kohsuke Kawaguchi
*/
-public class EnvVars extends TreeMap {
+public class EnvVars extends TreeMap {
private static final long serialVersionUID = 4320331661987259022L;
private static Logger LOGGER = Logger.getLogger(EnvVars.class.getName());
/**
@@ -86,7 +85,7 @@ public class EnvVars extends TreeMap {
* So this property remembers that information.
*/
private Platform platform;
-
+
/**
* Gets the platform for which these env vars targeted.
* @since 2.144
@@ -104,11 +103,12 @@ public class EnvVars extends TreeMap {
public void setPlatform(@NonNull Platform platform) {
this.platform = platform;
}
+
public EnvVars() {
- super(CaseInsensitiveComparator.INSTANCE);
+ super(String.CASE_INSENSITIVE_ORDER);
}
- public EnvVars(@NonNull Map m) {
+ public EnvVars(@NonNull Map m) {
this();
putAll(m);
@@ -123,7 +123,7 @@ public EnvVars(@NonNull Map m) {
@SuppressWarnings("CopyConstructorMissesField") // does not set #platform, see its Javadoc
public EnvVars(@NonNull EnvVars m) {
// this constructor is so that in future we can get rid of the downcasting.
- this((Map)m);
+ this((Map) m);
}
/**
@@ -131,10 +131,10 @@ public EnvVars(@NonNull EnvVars m) {
*/
public EnvVars(String... keyValuePairs) {
this();
- if(keyValuePairs.length%2!=0)
+ if (keyValuePairs.length % 2 != 0)
throw new IllegalArgumentException(Arrays.asList(keyValuePairs).toString());
- for( int i=0; i0) {
- String realKey = key.substring(0,idx);
+ if (idx > 0) {
+ String realKey = key.substring(0, idx);
String v = get(realKey);
- if(v==null) v=value;
+ if (v == null) v = value;
else {
// we might be handling environment variables for a agent that can have different path separator
- // than the master, so the following is an attempt to get it right.
+ // than the controller, so the following is an attempt to get it right.
// it's still more error prone that I'd like.
- char ch = platform==null ? File.pathSeparatorChar : platform.pathSeparator;
- v=value+ch+v;
+ char ch = platform == null ? File.pathSeparatorChar : platform.pathSeparator;
+ v = value + ch + v;
}
- put(realKey,v);
+ put(realKey, v);
return;
}
- put(key,value);
+ put(key, value);
}
/**
@@ -173,18 +173,18 @@ public void override(String key, String value) {
* See {@link #override(String, String)}.
* @return this
*/
- public EnvVars overrideAll(Map all) {
+ public EnvVars overrideAll(Map all) {
for (Map.Entry e : all.entrySet()) {
- override(e.getKey(),e.getValue());
+ override(e.getKey(), e.getValue());
}
return this;
}
/**
* Calculates the order to override variables.
- *
+ *
* Sort variables with topological sort with their reference graph.
- *
+ *
* This is package accessible for testing purpose.
*/
static class OverrideOrderCalculator {
@@ -194,30 +194,31 @@ static class OverrideOrderCalculator {
private static class TraceResolver implements VariableResolver {
private final Comparator super String> comparator;
public Set referredVariables;
-
+
TraceResolver(Comparator super String> comparator) {
this.comparator = comparator;
clear();
}
-
+
public void clear() {
referredVariables = new TreeSet<>(comparator);
}
-
+
+ @Override
public String resolve(String name) {
referredVariables.add(name);
return "";
}
}
-
+
private static class VariableReferenceSorter extends CyclicGraphDetector {
// map from a variable to a set of variables that variable refers.
private final Map> refereeSetMap;
-
+
VariableReferenceSorter(Map> refereeSetMap) {
this.refereeSetMap = refereeSetMap;
}
-
+
@Override
protected Iterable extends String> getEdges(String n) {
// return variables referred from the variable.
@@ -230,40 +231,40 @@ protected Iterable extends String> getEdges(String n) {
}
private final Comparator super String> comparator;
-
+
@NonNull
private final EnvVars target;
@NonNull
- private final Map overrides;
-
+ private final Map overrides;
+
private Map> refereeSetMap;
private List orderedVariableNames;
-
- OverrideOrderCalculator(@NonNull EnvVars target, @NonNull Map overrides) {
+
+ OverrideOrderCalculator(@NonNull EnvVars target, @NonNull Map overrides) {
comparator = target.comparator();
this.target = target;
this.overrides = overrides;
scan();
}
-
+
public List getOrderedVariableNames() {
return orderedVariableNames;
}
-
+
// Cut the reference to the variable in a cycle.
private void cutCycleAt(String referee, List cycle) {
// cycle contains variables in referrer-to-referee order.
// This should not be negative, for the first and last one is same.
int refererIndex = cycle.lastIndexOf(referee) - 1;
-
- assert(refererIndex >= 0);
+
+ assert refererIndex >= 0;
String referrer = cycle.get(refererIndex);
boolean removed = refereeSetMap.get(referrer).remove(referee);
- assert(removed);
- LOGGER.warning(String.format("Cyclic reference detected: %s", Util.join(cycle," -> ")));
+ assert removed;
+ LOGGER.warning(String.format("Cyclic reference detected: %s", String.join(" -> ", cycle)));
LOGGER.warning(String.format("Cut the reference %s -> %s", referrer, referee));
}
-
+
// Cut the variable reference in a cycle.
private void cutCycle(List cycle) {
// if an existing variable is contained in that cycle,
@@ -274,27 +275,27 @@ private void cutCycle(List cycle) {
// PATH1=/usr/local/bin:${PATH}
// PATH=/opt/something/bin:${PATH1}
// then consider reference PATH1 -> PATH can be ignored.
- for (String referee: cycle) {
+ for (String referee : cycle) {
if (target.containsKey(referee)) {
cutCycleAt(referee, cycle);
return;
}
}
-
+
// if not, cut the reference to the first one.
cutCycleAt(cycle.get(0), cycle);
}
-
+
/**
* Scan all variables and list all referring variables.
*/
public void scan() {
refereeSetMap = new TreeMap<>(comparator);
List extendingVariableNames = new ArrayList<>();
-
+
TraceResolver resolver = new TraceResolver(comparator);
-
- for (Map.Entry entry: overrides.entrySet()) {
+
+ for (Map.Entry entry : overrides.entrySet()) {
if (entry.getKey().indexOf('+') > 0) {
// XYZ+AAA variables should be always processed in last.
extendingVariableNames.add(entry.getKey());
@@ -302,20 +303,20 @@ public void scan() {
}
resolver.clear();
Util.replaceMacro(entry.getValue(), resolver);
-
+
// Variables directly referred from the current scanning variable.
Set refereeSet = resolver.referredVariables;
// Ignore self reference.
refereeSet.remove(entry.getKey());
refereeSetMap.put(entry.getKey(), refereeSet);
}
-
+
VariableReferenceSorter sorter;
- while(true) {
+ while (true) {
sorter = new VariableReferenceSorter(refereeSetMap);
try {
sorter.run(refereeSetMap.keySet());
- } catch(CycleDetectedException e) {
+ } catch (CycleDetectedException e) {
// cyclic reference found.
// cut the cycle and retry.
@SuppressWarnings("unchecked")
@@ -325,15 +326,15 @@ public void scan() {
}
break;
}
-
+
// When A refers B, the last appearance of B always comes after
// the last appearance of A.
List reversedDuplicatedOrder = new ArrayList<>(sorter.getSorted());
Collections.reverse(reversedDuplicatedOrder);
-
+
orderedVariableNames = new ArrayList<>(overrides.size());
- for(String key: reversedDuplicatedOrder) {
- if(overrides.containsKey(key) && !orderedVariableNames.contains(key)) {
+ for (String key : reversedDuplicatedOrder) {
+ if (overrides.containsKey(key) && !orderedVariableNames.contains(key)) {
orderedVariableNames.add(key);
}
}
@@ -341,14 +342,14 @@ public void scan() {
orderedVariableNames.addAll(extendingVariableNames);
}
}
-
+
/**
* Overrides all values in the map by the given map. Expressions in values will be expanded.
* See {@link #override(String, String)}.
* @return {@code this}
*/
- public EnvVars overrideExpandingAll(@NonNull Map all) {
+ public EnvVars overrideExpandingAll(@NonNull Map all) {
for (String key : new OverrideOrderCalculator(this, all).getOrderedVariableNames()) {
override(key, expand(all.get(key)));
}
@@ -358,11 +359,11 @@ public EnvVars overrideExpandingAll(@NonNull Map all) {
/**
* Resolves environment variables against each other.
*/
- public static void resolve(Map env) {
- for (Map.Entry entry: env.entrySet()) {
- entry.setValue(Util.replaceMacro(entry.getValue(), env));
- }
- }
+ public static void resolve(Map env) {
+ for (Map.Entry entry : env.entrySet()) {
+ entry.setValue(Util.replaceMacro(entry.getValue(), env));
+ }
+ }
/**
* Convenience message
@@ -370,14 +371,14 @@ public static void resolve(Map env) {
**/
public String get(String key, String defaultValue) {
String v = get(key);
- if (v==null) v=defaultValue;
+ if (v == null) v = defaultValue;
return v;
}
@Override
public String put(String key, String value) {
- if (value==null) throw new IllegalArgumentException("Null value not allowed as an environment variable: "+key);
- return super.put(key,value);
+ if (value == null) throw new IllegalArgumentException("Null value not allowed as an environment variable: " + key);
+ return super.put(key, value);
}
/**
@@ -385,8 +386,8 @@ public String put(String key, String value) {
* @since 1.556
*/
public void putIfNotNull(String key, String value) {
- if (value!=null)
- put(key,value);
+ if (value != null)
+ put(key, value);
}
/**
@@ -397,14 +398,14 @@ public void putAllNonNull(Map map) {
map.forEach(this::putIfNotNull);
}
-
+
/**
* Takes a string that looks like "a=b" and adds that to this map.
*/
public void addLine(String line) {
int sep = line.indexOf('=');
- if(sep > 0) {
- put(line.substring(0,sep),line.substring(sep+1));
+ if (sep > 0) {
+ put(line.substring(0, sep), line.substring(sep + 1));
}
}
@@ -432,15 +433,17 @@ public static EnvVars createCookie() {
* A fresh copy that can be owned and modified by the caller.
*/
public static EnvVars getRemote(VirtualChannel channel) throws IOException, InterruptedException {
- if(channel==null)
- return new EnvVars("N/A","N/A");
+ if (channel == null)
+ return new EnvVars("N/A", "N/A");
return channel.call(new GetEnvVars());
}
- private static final class GetEnvVars extends MasterToSlaveCallable {
+ private static final class GetEnvVars extends MasterToSlaveCallable {
+ @Override
public EnvVars call() {
return new EnvVars(EnvVars.masterEnvVars);
}
+
private static final long serialVersionUID = 1L;
}
@@ -449,19 +452,19 @@ public EnvVars call() {
*
*
* Despite what the name might imply, this is the environment variable
- * of the current JVM process. And therefore, it is Jenkins master's environment
- * variables only when you access this from the master.
+ * of the current JVM process. And therefore, it is the Jenkins controller's
+ * environment variables only when you access this from the controller.
*
*
* If you access this field from agents, then this is the environment
* variable of the agent.
*/
- public static final Map masterEnvVars = initMaster();
+ public static final Map masterEnvVars = initMaster();
private static EnvVars initMaster() {
EnvVars vars = new EnvVars(System.getenv());
vars.platform = Platform.current();
- if(Main.isUnitTest || Main.isDevelopmentMode)
+ if (Main.isUnitTest || Main.isDevelopmentMode)
// if unit test is launched with maven debug switch,
// we need to prevent forked Maven processes from seeing it, or else
// they'll hang
diff --git a/core/src/main/java/hudson/ExpressionFactory2.java b/core/src/main/java/hudson/ExpressionFactory2.java
index a3bd134319c2..7fcec22e7604 100644
--- a/core/src/main/java/hudson/ExpressionFactory2.java
+++ b/core/src/main/java/hudson/ExpressionFactory2.java
@@ -1,17 +1,16 @@
package hudson;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.apache.commons.jelly.JellyContext;
import org.apache.commons.jelly.JellyException;
import org.apache.commons.jelly.expression.Expression;
import org.apache.commons.jelly.expression.ExpressionFactory;
import org.apache.commons.jelly.expression.ExpressionSupport;
import org.apache.commons.jexl.JexlContext;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.springframework.security.access.AccessDeniedException;
@@ -22,6 +21,7 @@
* @author Kohsuke Kawaguchi
*/
final class ExpressionFactory2 implements ExpressionFactory {
+ @Override
public Expression createExpression(String text) throws JellyException {
try {
return new JexlExpression(
@@ -63,21 +63,23 @@ public String toString() {
// Expression interface
//-------------------------------------------------------------------------
+ @Override
public String getExpressionText() {
return "${" + expression.getExpression() + "}";
}
+ @Override
public Object evaluate(JellyContext context) {
try {
CURRENT_CONTEXT.set(context);
- JexlContext jexlContext = new JellyJexlContext( context );
+ JexlContext jexlContext = new JellyJexlContext(context);
return expression.evaluate(jexlContext);
} catch (AccessDeniedException e) {
// let the security exception pass through
throw e;
} catch (Exception e) {
StaplerRequest currentRequest = Stapler.getCurrentRequest();
- LOGGER.log(Level.WARNING,"Caught exception evaluating: " + expression + " in " + (currentRequest != null ? currentRequest.getOriginalRequestURI() : "?") + ". Reason: " + e, e);
+ LOGGER.log(Level.WARNING, "Caught exception evaluating: " + expression + " in " + (currentRequest != null ? currentRequest.getOriginalRequestURI() : "?") + ". Reason: " + e, e);
return null;
} finally {
CURRENT_CONTEXT.set(null);
@@ -91,14 +93,16 @@ static final class JellyJexlContext implements JexlContext {
private Map vars;
JellyJexlContext(JellyContext context) {
- this.vars = new JellyMap( context );
+ this.vars = new JellyMap(context);
}
+ @Override
public void setVars(Map vars) {
this.vars.clear();
- this.vars.putAll( vars );
+ this.vars.putAll(vars);
}
+ @Override
public Map getVars() {
return this.vars;
}
@@ -113,50 +117,62 @@ static final class JellyMap implements Map {
this.context = context;
}
+ @Override
public Object get(Object key) {
- return context.getVariable( (String) key );
+ return context.getVariable((String) key);
}
+ @Override
public void clear() {
// not implemented
}
+ @Override
public boolean containsKey(Object key) {
- return ( get( key ) != null );
+ return get(key) != null;
}
+ @Override
public boolean containsValue(Object value) {
return false;
}
+ @Override
public Set entrySet() {
return null;
}
+ @Override
public boolean isEmpty() {
return false;
}
+ @Override
public Set keySet() {
return null;
}
+ @Override
public Object put(Object key, Object value) {
return null;
}
+ @Override
public void putAll(Map t) {
// not implemented
}
+ @Override
public Object remove(Object key) {
return null;
}
+ @Override
public int size() {
return -1;
}
+ @Override
public Collection values() {
return null;
}
diff --git a/core/src/main/java/hudson/Extension.java b/core/src/main/java/hudson/Extension.java
index 1ca863d2f4f5..b240e37f87db 100644
--- a/core/src/main/java/hudson/Extension.java
+++ b/core/src/main/java/hudson/Extension.java
@@ -21,18 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
package hudson;
-import jenkins.YesNoMaybe;
-import net.java.sezpoz.Indexable;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static jenkins.YesNoMaybe.MAYBE;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import static jenkins.YesNoMaybe.MAYBE;
+import jenkins.YesNoMaybe;
+import net.java.sezpoz.Indexable;
/**
* Marks a field, a method, or a class for automatic discovery, so that Hudson can locate
diff --git a/core/src/main/java/hudson/ExtensionComponent.java b/core/src/main/java/hudson/ExtensionComponent.java
index e4e35ebe1d45..4ef48d08008d 100644
--- a/core/src/main/java/hudson/ExtensionComponent.java
+++ b/core/src/main/java/hudson/ExtensionComponent.java
@@ -50,11 +50,11 @@ public ExtensionComponent(T instance, double ordinal) {
}
public ExtensionComponent(T instance, Extension annotation) {
- this(instance,annotation.ordinal());
+ this(instance, annotation.ordinal());
}
public ExtensionComponent(T instance) {
- this(instance,0);
+ this(instance, 0);
}
/**
@@ -79,12 +79,13 @@ public T getInstance() {
* For example, {@code component.isDescriptorOf(Builder.class)}
*/
public boolean isDescriptorOf(Class extends Describable> c) {
- return instance instanceof Descriptor && ((Descriptor)instance).isSubTypeOf(c);
+ return instance instanceof Descriptor && ((Descriptor) instance).isSubTypeOf(c);
}
/**
* Sort {@link ExtensionComponent}s in the descending order of {@link #ordinal()}.
*/
+ @Override
public int compareTo(ExtensionComponent that) {
double a = this.ordinal();
double b = that.ordinal();
diff --git a/core/src/main/java/hudson/ExtensionFinder.java b/core/src/main/java/hudson/ExtensionFinder.java
index 048e69bc9fef..5bddd008f5f0 100644
--- a/core/src/main/java/hudson/ExtensionFinder.java
+++ b/core/src/main/java/hudson/ExtensionFinder.java
@@ -21,10 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
package hudson;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule;
import com.google.inject.Binding;
import com.google.inject.Guice;
@@ -40,18 +39,7 @@
import hudson.init.InitMilestone;
import hudson.model.Descriptor;
import hudson.model.Hudson;
-import jenkins.ExtensionComponentSet;
-import jenkins.ExtensionFilter;
-import jenkins.ExtensionRefreshException;
-import jenkins.ProxyInjector;
-import jenkins.model.Jenkins;
-import net.java.sezpoz.Index;
-import net.java.sezpoz.IndexItem;
-import org.kohsuke.accmod.Restricted;
-import org.kohsuke.accmod.restrictions.NoExternalUse;
-import org.springframework.util.ClassUtils;
-
-import javax.annotation.PostConstruct;
+import jakarta.annotation.PostConstruct;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
@@ -62,13 +50,23 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+import jenkins.ExtensionComponentSet;
+import jenkins.ExtensionFilter;
+import jenkins.ExtensionRefreshException;
+import jenkins.ProxyInjector;
+import jenkins.model.Jenkins;
+import net.java.sezpoz.Index;
+import net.java.sezpoz.IndexItem;
+import org.kohsuke.accmod.Restricted;
+import org.kohsuke.accmod.restrictions.NoExternalUse;
+import org.springframework.util.ClassUtils;
/**
* Discovers the implementations of an extension point.
@@ -101,7 +99,7 @@ public Collection findExtensions(Class type, Hudson hudson) {
*/
public boolean isRefreshable() {
try {
- return getClass().getMethod("refresh").getDeclaringClass()!=ExtensionFinder.class;
+ return getClass().getMethod("refresh").getDeclaringClass() != ExtensionFinder.class;
} catch (NoSuchMethodException e) {
return false;
}
@@ -156,7 +154,7 @@ public Collection> _find(Class type, Hudson hudson)
}
/**
- * Performs class initializations without creating instances.
+ * Performs class initializations without creating instances.
*
* If two threads try to initialize classes in the opposite order, a dead lock will ensue,
* and we can get into a similar situation with {@link ExtensionFinder}s.
@@ -230,7 +228,7 @@ protected GuiceExtensionAnnotation(Class annotationType) {
protected abstract boolean isOptional(T annotation);
}
-
+
/**
* Discovers components via sezpoz but instantiates them by using Guice.
*/
@@ -249,15 +247,15 @@ public static class GuiceFinder extends ExtensionFinder {
* Sezpoz index we are currently using in {@link #container} (and its ancestors.)
* Needed to compute delta.
*/
- private List> sezpozIndex;
+ private List> sezpozIndex;
- private final Map annotations = new HashMap<>();
+ private final Map annotations = new HashMap<>();
private final Sezpoz moduleFinder = new Sezpoz();
/**
* Map from {@link GuiceExtensionAnnotation#annotationType} to {@link GuiceExtensionAnnotation}
*/
- private Map,GuiceExtensionAnnotation>> extensionAnnotations = new HashMap<>();
+ private Map, GuiceExtensionAnnotation>> extensionAnnotations = new HashMap<>();
public GuiceFinder() {
refreshExtensionAnnotations();
@@ -283,14 +281,15 @@ protected void configure() {
container = Guice.createInjector(modules);
sezpozIndex = extensions.getLoadedIndex();
} catch (Throwable e) {
- LOGGER.log(Level.SEVERE, "Failed to create Guice container from all the plugins",e);
+ LOGGER.log(Level.SEVERE, "Failed to create Guice container from all the plugins", e);
// failing to load all bindings are disastrous, so recover by creating minimum that works
// by just including the core
container = Guice.createInjector(new SezpozModule(loadSezpozIndices(Jenkins.class.getClassLoader())));
}
// expose Injector via lookup mechanism for interop with non-Guice clients
- Jenkins.get().lookup.set(Injector.class,new ProxyInjector() {
+ Jenkins.get().lookup.set(Injector.class, new ProxyInjector() {
+ @Override
protected Injector resolve() {
return getContainer();
}
@@ -300,16 +299,18 @@ protected Injector resolve() {
private void refreshExtensionAnnotations() {
for (ExtensionComponent ec : moduleFinder.find(GuiceExtensionAnnotation.class, Hudson.getInstance())) {
GuiceExtensionAnnotation gea = ec.getInstance();
- extensionAnnotations.put(gea.annotationType,gea);
+ extensionAnnotations.put(gea.annotationType, gea);
}
}
- private ImmutableList> loadSezpozIndices(ClassLoader classLoader) {
- List> indices = new ArrayList<>();
+ private List> loadSezpozIndices(ClassLoader classLoader) {
+ List> indices = new ArrayList<>();
for (GuiceExtensionAnnotation> gea : extensionAnnotations.values()) {
- Iterables.addAll(indices, Index.load(gea.annotationType, Object.class, classLoader));
+ for (IndexItem, Object> indexItem : Index.load(gea.annotationType, Object.class, classLoader)) {
+ indices.add(indexItem);
+ }
}
- return ImmutableList.copyOf(indices);
+ return Collections.unmodifiableList(indices);
}
public Injector getContainer() {
@@ -330,7 +331,7 @@ public synchronized ExtensionComponentSet refresh() throws ExtensionRefreshExcep
// figure out newly discovered sezpoz components
List> delta = new ArrayList<>();
for (Class extends Annotation> annotationType : extensionAnnotations.keySet()) {
- delta.addAll(Sezpoz.listDelta(annotationType,sezpozIndex));
+ delta.addAll(Sezpoz.listDelta(annotationType, sezpozIndex));
}
SezpozModule deltaExtensions = new SezpozModule(delta);
@@ -357,19 +358,19 @@ public Collection> find(Class type) {
}
};
} catch (Throwable e) {
- LOGGER.log(Level.SEVERE, "Failed to create Guice container from newly added plugins",e);
+ LOGGER.log(Level.SEVERE, "Failed to create Guice container from newly added plugins", e);
throw new ExtensionRefreshException(e);
}
}
- private Object instantiate(IndexItem,Object> item) {
+ private Object instantiate(IndexItem, Object> item) {
try {
return item.instance();
} catch (LinkageError | Exception e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING,
- "Failed to load "+item.className(), e);
+ "Failed to load " + item.className(), e);
}
return null;
}
@@ -384,22 +385,23 @@ private boolean isActive(Annotation annotation, AnnotatedElement e) {
return gea.isActive(e);
}
+ @Override
public Collection> find(Class type, Hudson jenkins) {
// the find method contract requires us to traverse all known components
List> result = new ArrayList<>();
- for (Injector i=container; i!=null; i=i.getParent()) {
+ for (Injector i = container; i != null; i = i.getParent()) {
_find(type, result, i);
}
return result;
}
private void _find(Class type, List> result, Injector container) {
- for (Entry, Binding>> e : container.getBindings().entrySet()) {
+ for (Map.Entry, Binding>> e : container.getBindings().entrySet()) {
if (type.isAssignableFrom(e.getKey().getTypeLiteral().getRawType())) {
Annotation a = annotations.get(e.getKey());
Object o = e.getValue().getProvider().get();
- if (o!=null) {
- GuiceExtensionAnnotation gea = a!=null ? extensionAnnotations.get(a.annotationType()) : null;
+ if (o != null) {
+ GuiceExtensionAnnotation gea = a != null ? extensionAnnotations.get(a.annotationType()) : null;
result.add(new ExtensionComponent<>(type.cast(o), gea != null ? gea.getOrdinal(a) : 0));
}
}
@@ -424,15 +426,19 @@ public void scout(Class extensionType, Hudson hudson) {
*/
public static final Scope FAULT_TOLERANT_SCOPE = new FaultTolerantScope(true);
private static final Scope QUIET_FAULT_TOLERANT_SCOPE = new FaultTolerantScope(false);
-
+
private static final class FaultTolerantScope implements Scope {
private final boolean verbose;
+
FaultTolerantScope(boolean verbose) {
this.verbose = verbose;
}
+
+ @Override
public Provider scope(final Key key, final Provider unscoped) {
- final Provider base = Scopes.SINGLETON.scope(key,unscoped);
+ final Provider base = Scopes.SINGLETON.scope(key, unscoped);
return new Provider() {
+ @Override
public T get() {
try {
return base.get();
@@ -441,6 +447,7 @@ public T get() {
return null;
}
}
+
void error(Key key, Throwable x) {
LOGGER.log(verbose ? Level.WARNING : Level.FINE, "Failed to instantiate " + key + "; skipping this component", x);
}
@@ -456,10 +463,10 @@ void error(Key key, Throwable x) {
* so that we can take advantage of dependency injection.
*/
private class SezpozModule extends AbstractModule implements ProvisionListener {
- private final List> index;
- private final List> loadedIndex;
+ private final List> index;
+ private final List> loadedIndex;
- SezpozModule(List> index) {
+ SezpozModule(List> index) {
this.index = index;
this.loadedIndex = new ArrayList<>();
}
@@ -479,6 +486,7 @@ private class SezpozModule extends AbstractModule implements ProvisionListener {
private void resolve(Class> c) {
resolve(c, new HashSet<>());
}
+
private void resolve(Class> c, Set> encountered) {
if (!encountered.add(c)) {
return;
@@ -499,8 +507,8 @@ private void resolve(Class> c, Set> encountered) {
}
}
LOGGER.log(Level.FINER, "{0} looks OK", c);
- } catch (Exception x) {
- throw new LinkageError("Failed to resolve "+c, x);
+ } catch (RuntimeException x) {
+ throw new LinkageError("Failed to resolve " + c, x);
}
}
@@ -510,26 +518,26 @@ protected void configure() {
bindListener(Matchers.any(), this);
- for (final IndexItem,Object> item : index) {
+ for (final IndexItem, Object> item : index) {
boolean optional = isOptional(item.annotation());
try {
AnnotatedElement e = item.element();
Annotation a = item.annotation();
- if (!isActive(a,e)) continue;
+ if (!isActive(a, e)) continue;
Scope scope = optional ? QUIET_FAULT_TOLERANT_SCOPE : FAULT_TOLERANT_SCOPE;
if (e instanceof Class) {
- Key key = Key.get((Class)e);
- resolve((Class)e);
- annotations.put(key,a);
+ Key key = Key.get((Class) e);
+ resolve((Class) e);
+ annotations.put(key, a);
bind(key).in(scope);
} else {
Class extType;
if (e instanceof Field) {
- extType = ((Field)e).getType();
+ extType = ((Field) e).getType();
} else
if (e instanceof Method) {
- extType = ((Method)e).getReturnType();
+ extType = ((Method) e).getReturnType();
} else {
throw new AssertionError();
}
@@ -538,32 +546,28 @@ protected void configure() {
// make unique key, because Guice wants that.
Key key = Key.get(extType, Names.named(item.className() + "." + item.memberName()));
- annotations.put(key,a);
- bind(key).toProvider(new Provider() {
- public Object get() {
- return instantiate(item);
- }
- }).in(scope);
+ annotations.put(key, a);
+ bind(key).toProvider(() -> instantiate(item)).in(scope);
}
loadedIndex.add(item);
- } catch (Exception|LinkageError e) {
+ } catch (Exception | LinkageError e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
LOGGER.log(optional ? Level.FINE : Level.WARNING,
- "Failed to load "+item.className(), e);
+ "Failed to load " + item.className(), e);
}
}
}
public List> getLoadedIndex() {
- return Collections.unmodifiableList(loadedIndex);
+ return Collections.unmodifiableList(new ArrayList<>(loadedIndex));
}
@Override
public void onProvision(ProvisionInvocation provision) {
final T instance = provision.provision();
if (instance == null) return;
- List methods = new LinkedList<>();
+ List methods = new ArrayList<>();
Class c = instance.getClass();
// find PostConstruct methods in class hierarchy, the one from parent class being first in list
@@ -576,7 +580,7 @@ public void onProvision(ProvisionInvocation provision) {
Arrays.stream(c.getDeclaredMethods())
.map(m -> getMethodAndInterfaceDeclarations(m, interfaces))
.flatMap(Collection::stream)
- .filter(m -> m.getAnnotation(PostConstruct.class) != null)
+ .filter(m -> m.getAnnotation(PostConstruct.class) != null || m.getAnnotation(javax.annotation.PostConstruct.class) != null)
.findFirst()
.ifPresent(method -> methods.add(0, method));
c = c.getSuperclass();
@@ -624,7 +628,7 @@ Collection getMethodAndInterfaceDeclarations(Method method, Collection> indices;
+ private volatile List> indices;
/**
* Loads indices (ideally once but as few times as possible), then reuse them later.
@@ -632,16 +636,16 @@ public static final class Sezpoz extends ExtensionFinder {
* {@link InitMilestone#PLUGINS_PREPARED} is attained, so this method is guaranteed to
* see all the classes and indices.
*/
- private List> getIndices() {
+ private List> getIndices() {
// this method cannot be synchronized because of a dead lock possibility in the following order of events:
// 1. thread X can start listing indices, locking this object 'SZ'
// 2. thread Y starts loading a class, locking a classloader 'CL'
// 3. thread X needs to load a class, now blocked on CL
// 4. thread Y decides to load extensions, now blocked on SZ.
// 5. dead lock
- if (indices==null) {
+ if (indices == null) {
ClassLoader cl = Jenkins.get().getPluginManager().uberClassLoader;
- indices = ImmutableList.copyOf(Index.load(Extension.class, Object.class, cl));
+ indices = Collections.unmodifiableList(StreamSupport.stream(Index.load(Extension.class, Object.class, cl).spliterator(), false).collect(Collectors.toList()));
}
return indices;
}
@@ -654,28 +658,28 @@ private List> getIndices() {
*/
@Override
public synchronized ExtensionComponentSet refresh() {
- final List> old = indices;
- if (old==null) return ExtensionComponentSet.EMPTY; // we haven't loaded anything
+ final List> old = indices;
+ if (old == null) return ExtensionComponentSet.EMPTY; // we haven't loaded anything
- final List> delta = listDelta(Extension.class,old);
+ final List> delta = listDelta(Extension.class, old);
- List> r = new ArrayList<>(old);
+ List> r = new ArrayList<>(old);
r.addAll(delta);
- indices = ImmutableList.copyOf(r);
+ indices = Collections.unmodifiableList(r);
return new ExtensionComponentSet() {
@Override
public Collection> find(Class type) {
- return _find(type,delta);
+ return _find(type, delta);
}
};
}
- static List> listDelta(Class annotationType, List extends IndexItem,Object>> old) {
+ static List> listDelta(Class annotationType, List extends IndexItem, Object>> old) {
// list up newly discovered components
- final List> delta = new ArrayList<>();
+ final List> delta = new ArrayList<>();
ClassLoader cl = Jenkins.get().getPluginManager().uberClassLoader;
- for (IndexItem ii : Index.load(annotationType, Object.class, cl)) {
+ for (IndexItem ii : Index.load(annotationType, Object.class, cl)) {
if (!old.contains(ii)) {
delta.add(ii);
}
@@ -683,29 +687,30 @@ static List> listDelta(Class annot
return delta;
}
+ @Override
public Collection> find(Class type, Hudson jenkins) {
- return _find(type,getIndices());
+ return _find(type, getIndices());
}
/**
* Finds all the matching {@link IndexItem}s that match the given type and instantiate them.
*/
- private Collection> _find(Class type, List> indices) {
+ private Collection> _find(Class type, List> indices) {
List> result = new ArrayList<>();
- for (IndexItem item : indices) {
+ for (IndexItem item : indices) {
try {
Class> extType = getClassFromIndex(item);
- if(type.isAssignableFrom(extType)) {
+ if (type.isAssignableFrom(extType)) {
Object instance = item.instance();
- if(instance!=null)
- result.add(new ExtensionComponent<>(type.cast(instance),item.annotation()));
+ if (instance != null)
+ result.add(new ExtensionComponent<>(type.cast(instance), item.annotation()));
}
- } catch (LinkageError|Exception e) {
+ } catch (LinkageError | Exception e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
- LOGGER.log(logLevel(item), "Failed to load "+item.className(), e);
+ LOGGER.log(logLevel(item), "Failed to load " + item.className(), e);
}
}
@@ -714,7 +719,7 @@ private Collection> _find(Class type, List