|
| 1 | +package org.jenkinsci.plugins.pipeline.maven; |
| 2 | + |
| 3 | +import hudson.DescriptorExtensionList; |
| 4 | +import hudson.model.Descriptor; |
| 5 | +import hudson.model.TaskListener; |
| 6 | +import jenkins.model.Jenkins; |
| 7 | + |
| 8 | +import java.io.PrintWriter; |
| 9 | +import java.util.ArrayList; |
| 10 | +import java.util.Collections; |
| 11 | +import java.util.HashMap; |
| 12 | +import java.util.List; |
| 13 | +import java.util.Map; |
| 14 | +import java.util.logging.Level; |
| 15 | +import java.util.logging.Logger; |
| 16 | + |
| 17 | +import javax.annotation.Nonnull; |
| 18 | +import javax.annotation.Nullable; |
| 19 | + |
| 20 | +/** |
| 21 | + * @author <a href="mailto:cleclerc@cloudbees.com">Cyrille Le Clerc</a> |
| 22 | + */ |
| 23 | +public enum MavenPublisherStrategy { |
| 24 | + |
| 25 | + IMPLICIT("Implicit") { |
| 26 | + /** |
| 27 | + * <p>Build the list of {@link MavenPublisher}s that should be invoked for the build execution of the given {@link TaskListener} |
| 28 | + * with the desired configuration. |
| 29 | + * </p> |
| 30 | + * <p> |
| 31 | + * The desired configuration is based on: |
| 32 | + * </p> |
| 33 | + * <ul> |
| 34 | + * <li>The default configuration of the publishers</li> |
| 35 | + * <li>The global configuration of the publishers defined in the "Global Tools Configuration' section</li> |
| 36 | + * <li>The configuration specified in the {@code withMaven(options=[...])} step</li> |
| 37 | + * </ul> |
| 38 | + * @param configuredPublishers |
| 39 | + * @param listener |
| 40 | + */ |
| 41 | + @Nonnull |
| 42 | + public List<MavenPublisher> buildPublishersList(@Nonnull List<MavenPublisher> configuredPublishers, @Nonnull TaskListener listener) { |
| 43 | + |
| 44 | + // configuration passed as parameter of "withMaven(options=[...]){}" |
| 45 | + // mavenPublisher.descriptor.id -> mavenPublisher |
| 46 | + Map<String, MavenPublisher> configuredPublishersById = new HashMap<>(); |
| 47 | + for (MavenPublisher mavenPublisher : configuredPublishers) { |
| 48 | + if (mavenPublisher == null) { |
| 49 | + // skip null publisher options injected by Jenkins pipeline, probably caused by a missing plugin |
| 50 | + } else { |
| 51 | + configuredPublishersById.put(mavenPublisher.getDescriptor().getId(), mavenPublisher); |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + // configuration defined globally |
| 56 | + Map<String, MavenPublisher> globallyConfiguredPublishersById = new HashMap<>(); |
| 57 | + GlobalPipelineMavenConfig globalPipelineMavenConfig = GlobalPipelineMavenConfig.get(); |
| 58 | + |
| 59 | + List<MavenPublisher> globallyConfiguredPublishers = globalPipelineMavenConfig == null ? Collections.<MavenPublisher>emptyList() : globalPipelineMavenConfig.getPublisherOptions(); |
| 60 | + if (globallyConfiguredPublishers == null) { |
| 61 | + globallyConfiguredPublishers = Collections.emptyList(); |
| 62 | + } |
| 63 | + for (MavenPublisher mavenPublisher : globallyConfiguredPublishers) { |
| 64 | + globallyConfiguredPublishersById.put(mavenPublisher.getDescriptor().getId(), mavenPublisher); |
| 65 | + } |
| 66 | + |
| 67 | + |
| 68 | + // mavenPublisher.descriptor.id -> mavenPublisher |
| 69 | + Map<String, MavenPublisher> defaultPublishersById = new HashMap<>(); |
| 70 | + DescriptorExtensionList<MavenPublisher, Descriptor<MavenPublisher>> descriptorList = Jenkins.getInstance().getDescriptorList(MavenPublisher.class); |
| 71 | + for (Descriptor<MavenPublisher> descriptor : descriptorList) { |
| 72 | + try { |
| 73 | + defaultPublishersById.put(descriptor.getId(), descriptor.clazz.newInstance()); |
| 74 | + } catch (InstantiationException | IllegalAccessException e) { |
| 75 | + PrintWriter error = listener.error("[withMaven] Exception instantiation default config for Maven Publisher '" + descriptor.getDisplayName() + "' / " + descriptor.getId() + ": " + e); |
| 76 | + e.printStackTrace(error); |
| 77 | + error.close(); |
| 78 | + LOGGER.log(Level.WARNING, "Exception instantiating " + descriptor.clazz + ": " + e, e); |
| 79 | + e.printStackTrace(); |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + |
| 84 | + if (LOGGER.isLoggable(Level.FINE)) { |
| 85 | + listener.getLogger().println("[withMaven] Maven Publishers with configuration provided by the pipeline: " + configuredPublishersById.values()); |
| 86 | + listener.getLogger().println("[withMaven] Maven Publishers with configuration defined globally: " + globallyConfiguredPublishersById.values()); |
| 87 | + listener.getLogger().println("[withMaven] Maven Publishers with default configuration: " + defaultPublishersById.values()); |
| 88 | + } |
| 89 | + |
| 90 | + // TODO FILTER |
| 91 | + List<MavenPublisher> results = new ArrayList<>(); |
| 92 | + for (Map.Entry<String, MavenPublisher> entry : defaultPublishersById.entrySet()) { |
| 93 | + String publisherId = entry.getKey(); |
| 94 | + MavenPublisher publisher = buildConfiguredMavenPublisher( |
| 95 | + configuredPublishersById.get(publisherId), |
| 96 | + globallyConfiguredPublishersById.get(publisherId), |
| 97 | + entry.getValue(), |
| 98 | + listener); |
| 99 | + results.add(publisher); |
| 100 | + } |
| 101 | + Collections.sort(results); |
| 102 | + return results; |
| 103 | + } |
| 104 | + }, |
| 105 | + |
| 106 | + EXPLICIT("Explicit") { |
| 107 | + @Nonnull |
| 108 | + @Override |
| 109 | + public List<MavenPublisher> buildPublishersList |
| 110 | + (@Nonnull List<MavenPublisher> configuredPublishers, @Nonnull TaskListener listener) { |
| 111 | + |
| 112 | + // filter null entries caused by missing plugins |
| 113 | + List<MavenPublisher> result = new ArrayList<>(); |
| 114 | + for(MavenPublisher publisher: configuredPublishers) { |
| 115 | + if (publisher != null) { |
| 116 | + result.add(publisher); |
| 117 | + } |
| 118 | + } |
| 119 | + |
| 120 | + if (LOGGER.isLoggable(Level.FINE)) { |
| 121 | + listener.getLogger().println("[withMaven] Maven Publishers: " + result); |
| 122 | + } |
| 123 | + return result; |
| 124 | + } |
| 125 | + }; |
| 126 | + final String description; |
| 127 | + |
| 128 | + MavenPublisherStrategy(String description) { |
| 129 | + this.description = description; |
| 130 | + } |
| 131 | + |
| 132 | + public MavenPublisher buildConfiguredMavenPublisher(@Nullable MavenPublisher pipelinePublisher, @Nullable MavenPublisher globallyConfiguredPublisher, @Nonnull MavenPublisher defaultPublisher, @Nonnull TaskListener listener) { |
| 133 | + |
| 134 | + MavenPublisher result; |
| 135 | + String logMessage; |
| 136 | + |
| 137 | + if (pipelinePublisher == null && globallyConfiguredPublisher == null) { |
| 138 | + result = defaultPublisher; |
| 139 | + logMessage = "default"; |
| 140 | + } else if (pipelinePublisher == null && globallyConfiguredPublisher != null) { |
| 141 | + result = globallyConfiguredPublisher; |
| 142 | + logMessage = "globally"; |
| 143 | + } else if (pipelinePublisher != null && globallyConfiguredPublisher == null) { |
| 144 | + result = pipelinePublisher; |
| 145 | + logMessage = "pipeline"; |
| 146 | + } else if (pipelinePublisher != null && globallyConfiguredPublisher != null) { |
| 147 | + // workaround FindBugs "Bug kind and pattern: NP - NP_NULL_ON_SOME_PATH" |
| 148 | + // check pipelinePublisher and globallyConfiguredPublisher are non null even if it is useless |
| 149 | + |
| 150 | + result = pipelinePublisher; |
| 151 | + logMessage = "pipeline"; |
| 152 | + listener.getLogger().println("[withMaven] WARNING merging publisher configuration defined in the 'Global Tool Configuration' and at the pipeline level is not yet supported." + |
| 153 | + " Use pipeline level configuration for '" + result.getDescriptor().getDisplayName() + "'"); |
| 154 | +// |
| 155 | +// PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(defaultPublisher); |
| 156 | +// for(PropertyDescriptor propertyDescriptor: propertyDescriptors) { |
| 157 | +// Method readMethod = propertyDescriptor.getReadMethod(); |
| 158 | +// Method writeMethod = propertyDescriptor.getWriteMethod(); |
| 159 | +// |
| 160 | +// Object defaultValue = readMethod.invoke(defaultPublisher); |
| 161 | +// Object globallyDefinedValue = readMethod.invoke(globallyConfiguredPublisher); |
| 162 | +// Object pipelineValue = readMethod.invoke(pipelinePublisher); |
| 163 | +// } |
| 164 | + } else { |
| 165 | + throw new IllegalStateException("Should not happen, workaround for Findbugs NP_NULL_ON_SOME_PATH above"); |
| 166 | + } |
| 167 | + |
| 168 | + if (LOGGER.isLoggable(Level.FINE)) |
| 169 | + listener.getLogger().println("[withMaven] Use " + logMessage + " defined publisher for '" + result.getDescriptor().getDisplayName() + "'"); |
| 170 | + return result; |
| 171 | + |
| 172 | + } |
| 173 | + |
| 174 | + public String getDescription() { |
| 175 | + return description; |
| 176 | + } |
| 177 | + |
| 178 | + /** |
| 179 | + * <p>Build the list of {@link MavenPublisher}s that should be invoked for the build execution of the given {@link TaskListener} |
| 180 | + * with the desired configuration. |
| 181 | + * </p> |
| 182 | + * <p> |
| 183 | + * The desired configuration is based on: |
| 184 | + * </p> |
| 185 | + * <ul> |
| 186 | + * <li>The default configuration of the publishers</li> |
| 187 | + * <li>The global configuration of the publishers defined in the "Global Tools Configuration' section</li> |
| 188 | + * <li>The configuration specified in the {@code withMaven(options=[...])} step</li> |
| 189 | + * </ul> |
| 190 | + * @param configuredPublishers |
| 191 | + * @param listener |
| 192 | + */ |
| 193 | + @Nonnull |
| 194 | + public abstract List<MavenPublisher> buildPublishersList(@Nonnull List<MavenPublisher> configuredPublishers, @Nonnull TaskListener listener); |
| 195 | + |
| 196 | + private final static Logger LOGGER = Logger.getLogger(MavenPublisherStrategy.class.getName()); |
| 197 | +} |
0 commit comments