1 package org.apache.maven.project.validation; 2 3 18 19 import org.apache.maven.artifact.Artifact; 20 import org.apache.maven.model.Build; 21 import org.apache.maven.model.Dependency; 22 import org.apache.maven.model.DependencyManagement; 23 import org.apache.maven.model.Model; 24 import org.apache.maven.model.Parent; 25 import org.apache.maven.model.Plugin; 26 import org.apache.maven.model.ReportPlugin; 27 import org.apache.maven.model.Reporting; 28 import org.apache.maven.model.Repository; 29 import org.apache.maven.model.Resource; 30 import org.codehaus.plexus.util.StringUtils; 31 32 import java.io.File ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 36 40 public class DefaultModelValidator 41 implements ModelValidator 42 { 43 private static final String ID_REGEX = "[A-Za-z0-9_\\-.]+"; 44 45 48 public ModelValidationResult validate( Model model ) 49 { 50 ModelValidationResult result = new ModelValidationResult(); 51 52 validateStringNotEmpty( "modelVersion", result, model.getModelVersion() ); 53 54 validateId( "groupId", result, model.getGroupId() ); 55 56 validateId( "artifactId", result, model.getArtifactId() ); 57 58 validateStringNotEmpty( "packaging", result, model.getPackaging() ); 59 60 if ( !model.getModules().isEmpty() && !"pom".equals( model.getPackaging() ) ) 61 { 62 result.addMessage( "Packaging '" + model.getPackaging() + "' is invalid. Aggregator projects " + 63 "require 'pom' as packaging." ); 64 } 65 66 Parent parent = model.getParent(); 67 if ( parent != null ) 68 { 69 if ( parent.getGroupId().equals( model.getGroupId() ) && 70 parent.getArtifactId().equals( model.getArtifactId() ) ) 71 { 72 result.addMessage( "The parent element cannot have the same ID as the project." ); 73 } 74 } 75 76 validateStringNotEmpty( "version", result, model.getVersion() ); 77 78 for ( Iterator it = model.getDependencies().iterator(); it.hasNext(); ) 79 { 80 Dependency d = (Dependency) it.next(); 81 82 validateId( "dependencies.dependency.artifactId", result, d.getArtifactId() ); 83 84 validateId( "dependencies.dependency.groupId", result, d.getGroupId() ); 85 86 validateStringNotEmpty( "dependencies.dependency.type", result, d.getType(), dependencySourceHint( d ) ); 87 88 validateStringNotEmpty( "dependencies.dependency.version", result, d.getVersion(), dependencySourceHint( d ) ); 89 90 if ( Artifact.SCOPE_SYSTEM.equals( d.getScope() ) ) 91 { 92 String systemPath = d.getSystemPath(); 93 94 if ( StringUtils.isEmpty( systemPath ) ) 95 { 96 result.addMessage( "For dependency " + d + ": system-scoped dependency must specify systemPath." ); 97 } 98 else 99 { 100 if ( ! new File ( systemPath ).isAbsolute() ) 101 { 102 result.addMessage( "For dependency " + d + ": system-scoped dependency must " + 103 "specify an absolute path systemPath." ); 104 } 105 } 106 } 107 else if ( StringUtils.isNotEmpty( d.getSystemPath() ) ) 108 { 109 result.addMessage( 110 "For dependency " + d + ": only dependency with system scope can specify systemPath." ); 111 } 112 } 113 114 DependencyManagement mgmt = model.getDependencyManagement(); 115 if ( mgmt != null ) 116 { 117 for ( Iterator it = mgmt.getDependencies().iterator(); it.hasNext(); ) 118 { 119 Dependency d = (Dependency) it.next(); 120 121 validateSubElementStringNotEmpty( d, "dependencyManagement.dependencies.dependency.artifactId", result, 122 d.getArtifactId() ); 123 124 validateSubElementStringNotEmpty( d, "dependencyManagement.dependencies.dependency.groupId", result, 125 d.getGroupId() ); 126 127 if ( Artifact.SCOPE_SYSTEM.equals( d.getScope() ) ) 128 { 129 String systemPath = d.getSystemPath(); 130 131 if ( StringUtils.isEmpty( systemPath ) ) 132 { 133 result.addMessage( "For managed dependency " + d + ": system-scoped dependency must specify systemPath." ); 134 } 135 else 136 { 137 if ( ! new File ( systemPath ).isAbsolute() ) 138 { 139 result.addMessage( "For managed dependency " + d + ": system-scoped dependency must " + 140 "specify an absolute path systemPath." ); 141 } 142 } 143 } 144 else if ( StringUtils.isNotEmpty( d.getSystemPath() ) ) 145 { 146 result.addMessage( 147 "For managed dependency " + d + ": only dependency with system scope can specify systemPath." ); 148 } 149 } 150 } 151 152 Build build = model.getBuild(); 153 if ( build != null ) 154 { 155 for ( Iterator it = build.getPlugins().iterator(); it.hasNext(); ) 156 { 157 Plugin p = (Plugin) it.next(); 158 159 validateStringNotEmpty( "build.plugins.plugin.artifactId", result, p.getArtifactId() ); 160 161 validateStringNotEmpty( "build.plugins.plugin.groupId", result, p.getGroupId() ); 162 } 163 164 for ( Iterator it = build.getResources().iterator(); it.hasNext(); ) 165 { 166 Resource r = (Resource) it.next(); 167 168 validateStringNotEmpty( "build.resources.resource.directory", result, r.getDirectory() ); 169 } 170 171 for ( Iterator it = build.getTestResources().iterator(); it.hasNext(); ) 172 { 173 Resource r = (Resource) it.next(); 174 175 validateStringNotEmpty( "build.testResources.testResource.directory", result, r.getDirectory() ); 176 } 177 } 178 179 Reporting reporting = model.getReporting(); 180 if ( reporting != null ) 181 { 182 for ( Iterator it = reporting.getPlugins().iterator(); it.hasNext(); ) 183 { 184 ReportPlugin p = (ReportPlugin) it.next(); 185 186 validateStringNotEmpty( "reporting.plugins.plugin.artifactId", result, p.getArtifactId() ); 187 188 validateStringNotEmpty( "reporting.plugins.plugin.groupId", result, p.getGroupId() ); 189 } 190 } 191 192 validateRepositories( result, model.getRepositories(), "repositories.repository" ); 193 194 validateRepositories( result, model.getPluginRepositories(), "pluginRepositories.pluginRepository" ); 195 196 forcePluginExecutionIdCollision( model, result ); 197 198 return result; 199 } 200 201 private boolean validateId( String fieldName, ModelValidationResult result, String id ) 202 { 203 if ( !validateStringNotEmpty( fieldName, result, id ) ) 204 { 205 return false; 206 } 207 else 208 { 209 boolean match = id.matches( ID_REGEX ); 210 if ( !match ) 211 { 212 result.addMessage( "'" + fieldName + "' with value '" + id + "' does not match a valid id pattern." ); 213 } 214 return match; 215 } 216 } 217 218 private void validateRepositories( ModelValidationResult result, List repositories, String prefix ) 219 { 220 for ( Iterator it = repositories.iterator(); it.hasNext(); ) 221 { 222 Repository repository = (Repository) it.next(); 223 224 validateStringNotEmpty( prefix + ".id", result, repository.getId() ); 225 226 validateStringNotEmpty( prefix + ".url", result, repository.getUrl() ); 227 } 228 } 229 230 private void forcePluginExecutionIdCollision( Model model, ModelValidationResult result ) 231 { 232 Build build = model.getBuild(); 233 234 if ( build != null ) 235 { 236 List plugins = build.getPlugins(); 237 238 if ( plugins != null ) 239 { 240 for ( Iterator it = plugins.iterator(); it.hasNext(); ) 241 { 242 Plugin plugin = (Plugin) it.next(); 243 244 try 246 { 247 plugin.getExecutionsAsMap(); 248 } 249 catch ( IllegalStateException collisionException ) 250 { 251 result.addMessage( collisionException.getMessage() ); 252 } 253 } 254 } 255 } 256 } 257 258 259 263 271 private String dependencySourceHint( Dependency d ) 272 { 273 return d.getGroupId() + ":" + d.getArtifactId(); 274 } 275 276 private boolean validateStringNotEmpty( String fieldName, ModelValidationResult result, String string ) 277 { 278 return validateStringNotEmpty( fieldName, result, string, null ); 279 } 280 281 289 private boolean validateStringNotEmpty( String fieldName, ModelValidationResult result, String string, String sourceHint ) 290 { 291 if ( !validateNotNull( fieldName, result, string, sourceHint ) ) 292 { 293 return false; 294 } 295 296 if ( string.length() > 0 ) 297 { 298 return true; 299 } 300 301 if ( sourceHint != null ) 302 { 303 result.addMessage( "'" + fieldName + "' is missing for " + sourceHint ); 304 } 305 else 306 { 307 result.addMessage( "'" + fieldName + "' is missing." ); 308 } 309 310 311 return false; 312 } 313 314 322 private boolean validateSubElementStringNotEmpty( Object subElementInstance, String fieldName, 323 ModelValidationResult result, String string ) 324 { 325 if ( !validateSubElementNotNull( subElementInstance, fieldName, result, string ) ) 326 { 327 return false; 328 } 329 330 if ( string.length() > 0 ) 331 { 332 return true; 333 } 334 335 result.addMessage( "In " + subElementInstance + ":\n\n -> '" + fieldName + "' is missing." ); 336 337 return false; 338 } 339 340 347 private boolean validateNotNull( String fieldName, ModelValidationResult result, Object object, String sourceHint ) 348 { 349 if ( object != null ) 350 { 351 return true; 352 } 353 354 if ( sourceHint != null ) 355 { 356 result.addMessage( "'" + fieldName + "' is missing for " + sourceHint ); 357 } 358 else 359 { 360 result.addMessage( "'" + fieldName + "' is missing." ); 361 } 362 363 return false; 364 } 365 366 373 private boolean validateSubElementNotNull( Object subElementInstance, String fieldName, 374 ModelValidationResult result, Object object ) 375 { 376 if ( object != null ) 377 { 378 return true; 379 } 380 381 result.addMessage( "In " + subElementInstance + ":\n\n -> '" + fieldName + "' is missing." ); 382 383 return false; 384 } 385 } 386 | Popular Tags |