001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.enforcer.rules; 020 021import javax.inject.Inject; 022import javax.inject.Named; 023 024import java.util.ArrayList; 025import java.util.Collections; 026import java.util.List; 027import java.util.Objects; 028 029import org.apache.maven.artifact.repository.ArtifactRepository; 030import org.apache.maven.enforcer.rule.api.EnforcerRuleException; 031import org.apache.maven.project.MavenProject; 032 033/** 034 * This rule checks that this project's maven session whether have banned repositories. 035 * 036 * @author <a href="mailto:wangyf2010@gmail.com">Simon Wang</a> 037 */ 038@Named("bannedRepositories") 039public final class BannedRepositories extends AbstractStandardEnforcerRule { 040 041 // ---------------------------------------------------------------------- 042 // Mojo parameters 043 // ---------------------------------------------------------------------- 044 045 /** 046 * Specify explicitly banned non-plugin repositories. This is a list of repository url patterns. Support wildcard 047 * "*". 048 */ 049 private List<String> bannedRepositories = Collections.emptyList(); 050 051 /** 052 * Specify explicitly banned plugin repositories. This is a list of repository url patterns. Support wildcard "*". 053 */ 054 private List<String> bannedPluginRepositories = Collections.emptyList(); 055 056 /** 057 * Specify explicitly allowed non-plugin repositories, then all others repositories would be banned. This is a list 058 * of repository url patterns. Support wildcard "*". 059 */ 060 private List<String> allowedRepositories = Collections.emptyList(); 061 062 /** 063 * Specify explicitly allowed plugin repositories, then all others repositories would be banned. This is a list of 064 * repository url patterns. Support wildcard "*". 065 */ 066 private List<String> allowedPluginRepositories = Collections.emptyList(); 067 068 private final MavenProject project; 069 070 @Inject 071 public BannedRepositories(MavenProject project) { 072 this.project = Objects.requireNonNull(project); 073 } 074 075 // ---------------------------------------------------------------------- 076 // Public methods 077 // ---------------------------------------------------------------------- 078 079 @Override 080 public void execute() throws EnforcerRuleException { 081 082 List<ArtifactRepository> resultBannedRepos = checkRepositories( 083 project.getRemoteArtifactRepositories(), this.allowedRepositories, this.bannedRepositories); 084 085 List<ArtifactRepository> resultBannedPluginRepos = checkRepositories( 086 project.getPluginArtifactRepositories(), this.allowedPluginRepositories, this.bannedPluginRepositories); 087 088 String repoErrMsg = populateErrorMessage(resultBannedRepos, " "); 089 String pluginRepoErrMsg = populateErrorMessage(resultBannedPluginRepos, " plugin "); 090 091 String errMsg = repoErrMsg + pluginRepoErrMsg; 092 093 if (errMsg != null && !errMsg.isEmpty()) { 094 throw new EnforcerRuleException(errMsg); 095 } 096 } 097 098 // ---------------------------------------------------------------------- 099 // Protected methods 100 // ---------------------------------------------------------------------- 101 102 protected void setBannedRepositories(List<String> bannedRepositories) { 103 this.bannedRepositories = bannedRepositories; 104 } 105 106 protected void setAllowedRepositories(List<String> allowedRepositories) { 107 this.allowedRepositories = allowedRepositories; 108 } 109 110 protected void setAllowedPluginRepositories(List<String> allowedPluginRepositories) { 111 this.allowedPluginRepositories = allowedPluginRepositories; 112 } 113 114 // ---------------------------------------------------------------------- 115 // Private methods 116 // ---------------------------------------------------------------------- 117 118 /** 119 * Check whether specified repositories have banned repositories. 120 * 121 * @param repositories: candidate repositories. 122 * @param includes : 'include' patterns. 123 * @param excludes : 'exclude' patterns. 124 * @return Banned repositories. 125 */ 126 private List<ArtifactRepository> checkRepositories( 127 List<ArtifactRepository> repositories, List<String> includes, List<String> excludes) { 128 129 getLog().debug(() -> String.format( 130 "Check repositories: %s, for includes=%s and excludes=%s", repositories, includes, excludes)); 131 132 List<ArtifactRepository> bannedRepos = new ArrayList<>(); 133 134 for (ArtifactRepository repo : repositories) { 135 String url = repo.getUrl().trim(); 136 if (includes.size() > 0 && !match(url, includes)) { 137 bannedRepos.add(repo); 138 continue; 139 } 140 141 if (excludes.size() > 0 && match(url, excludes)) { 142 bannedRepos.add(repo); 143 } 144 } 145 146 return bannedRepos; 147 } 148 149 private boolean match(String url, List<String> patterns) { 150 for (String pattern : patterns) { 151 if (this.match(url, pattern)) { 152 return true; 153 } 154 } 155 156 return false; 157 } 158 159 private boolean match(String text, String pattern) { 160 return text.matches(pattern.replace("?", ".?").replace("*", ".*?")); 161 } 162 163 private String populateErrorMessage(List<ArtifactRepository> resultBannedRepos, String errorMessagePrefix) { 164 StringBuffer errMsg = new StringBuffer(""); 165 if (!resultBannedRepos.isEmpty()) { 166 errMsg.append("Current maven session contains banned" + errorMessagePrefix 167 + "repository urls, please double check your pom or settings.xml:" + System.lineSeparator() 168 + getRepositoryUrlString(resultBannedRepos) + System.lineSeparator() + System.lineSeparator()); 169 } 170 171 return errMsg.toString(); 172 } 173 174 private String getRepositoryUrlString(List<ArtifactRepository> resultBannedRepos) { 175 StringBuilder urls = new StringBuilder(""); 176 for (ArtifactRepository repo : resultBannedRepos) { 177 urls.append(repo.getId() + " - " + repo.getUrl() + System.lineSeparator()); 178 } 179 return urls.toString(); 180 } 181 182 @Override 183 public String toString() { 184 return String.format( 185 "BannedRepositories[bannedRepositories=%s, bannedPluginRepositories=%s, allowedRepositories=%s, allowedPluginRepositories=%s", 186 bannedRepositories, bannedPluginRepositories, allowedRepositories, allowedPluginRepositories); 187 } 188}