View Javadoc
1   package org.apache.maven.project;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collections;
27  import java.util.HashMap;
28  import java.util.LinkedHashSet;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Set;
32  
33  import org.apache.maven.RepositoryUtils;
34  import org.apache.maven.artifact.Artifact;
35  import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
36  import org.apache.maven.model.Build;
37  import org.apache.maven.model.Model;
38  import org.apache.maven.model.Profile;
39  import org.apache.maven.model.building.DefaultModelBuildingRequest;
40  import org.apache.maven.model.building.DefaultModelProblem;
41  import org.apache.maven.model.building.FileModelSource;
42  import org.apache.maven.model.building.ModelBuilder;
43  import org.apache.maven.model.building.ModelBuildingException;
44  import org.apache.maven.model.building.ModelBuildingRequest;
45  import org.apache.maven.model.building.ModelBuildingResult;
46  import org.apache.maven.model.building.ModelProblem;
47  import org.apache.maven.model.building.ModelProcessor;
48  import org.apache.maven.model.building.ModelSource;
49  import org.apache.maven.model.building.StringModelSource;
50  import org.apache.maven.model.resolution.ModelResolver;
51  import org.apache.maven.repository.RepositorySystem;
52  import org.apache.maven.repository.internal.ArtifactDescriptorUtils;
53  import org.codehaus.plexus.component.annotations.Component;
54  import org.codehaus.plexus.component.annotations.Requirement;
55  import org.codehaus.plexus.logging.Logger;
56  import org.codehaus.plexus.util.Os;
57  import org.codehaus.plexus.util.StringUtils;
58  import org.eclipse.aether.RepositorySystemSession;
59  import org.eclipse.aether.RequestTrace;
60  import org.eclipse.aether.impl.RemoteRepositoryManager;
61  import org.eclipse.aether.repository.LocalRepositoryManager;
62  import org.eclipse.aether.repository.RemoteRepository;
63  import org.eclipse.aether.repository.WorkspaceRepository;
64  import org.eclipse.aether.resolution.ArtifactRequest;
65  import org.eclipse.aether.resolution.ArtifactResult;
66  import org.eclipse.aether.resolution.VersionRangeRequest;
67  import org.eclipse.aether.resolution.VersionRangeResolutionException;
68  import org.eclipse.aether.resolution.VersionRangeResult;
69  
70  /**
71   */
72  @Component( role = ProjectBuilder.class )
73  public class DefaultProjectBuilder
74      implements ProjectBuilder
75  {
76  
77      @Requirement
78      private Logger logger;
79  
80      @Requirement
81      private ModelBuilder modelBuilder;
82  
83      @Requirement
84      private ModelProcessor modelProcessor;
85  
86      @Requirement
87      private ProjectBuildingHelper projectBuildingHelper;
88  
89      @Requirement
90      private RepositorySystem repositorySystem;
91  
92      @Requirement
93      private org.eclipse.aether.RepositorySystem repoSystem;
94  
95      @Requirement
96      private RemoteRepositoryManager repositoryManager;
97  
98      @Requirement
99      private ProjectDependenciesResolver dependencyResolver;
100 
101     // ----------------------------------------------------------------------
102     // MavenProjectBuilder Implementation
103     // ----------------------------------------------------------------------
104 
105     public ProjectBuildingResult build( File pomFile, ProjectBuildingRequest request )
106         throws ProjectBuildingException
107     {
108         return build( pomFile, new FileModelSource( pomFile ), new InternalConfig( request, null ) );
109     }
110 
111     public ProjectBuildingResult build( ModelSource modelSource, ProjectBuildingRequest request )
112         throws ProjectBuildingException
113     {
114         return build( null, modelSource, new InternalConfig( request, null ) );
115     }
116 
117     private ProjectBuildingResult build( File pomFile, ModelSource modelSource, InternalConfig config )
118         throws ProjectBuildingException
119     {
120         ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
121 
122         try
123         {
124             ProjectBuildingRequest configuration = config.request;
125 
126             MavenProject project = configuration.getProject();
127 
128             List<ModelProblem> modelProblems = null;
129             Throwable error = null;
130 
131             if ( project == null )
132             {
133                 ModelBuildingRequest request = getModelBuildingRequest( config );
134 
135                 project = new MavenProject( repositorySystem, this, configuration, logger );
136 
137                 DefaultModelBuildingListener listener =
138                     new DefaultModelBuildingListener( project, projectBuildingHelper, configuration );
139                 request.setModelBuildingListener( listener );
140 
141                 request.setPomFile( pomFile );
142                 request.setModelSource( modelSource );
143                 request.setLocationTracking( true );
144 
145                 ModelBuildingResult result;
146                 try
147                 {
148                     result = modelBuilder.build( request );
149                 }
150                 catch ( ModelBuildingException e )
151                 {
152                     result = e.getResult();
153                     if ( result == null || result.getEffectiveModel() == null )
154                     {
155                         throw new ProjectBuildingException( e.getModelId(), e.getMessage(), pomFile, e );
156                     }
157                     // validation error, continue project building and delay failing to help IDEs
158                     error = e;
159                 }
160 
161                 modelProblems = result.getProblems();
162 
163                 initProject( project, Collections.<String, MavenProject> emptyMap(), result,
164                              new HashMap<File, Boolean>() );
165             }
166             else if ( configuration.isResolveDependencies() )
167             {
168                 projectBuildingHelper.selectProjectRealm( project );
169             }
170 
171             DependencyResolutionResult resolutionResult = null;
172 
173             if ( configuration.isResolveDependencies() )
174             {
175                 resolutionResult = resolveDependencies( project, config.session );
176             }
177 
178             ProjectBuildingResult result = new DefaultProjectBuildingResult( project, modelProblems, resolutionResult );
179 
180             if ( error != null )
181             {
182                 ProjectBuildingException e = new ProjectBuildingException( Arrays.asList( result ) );
183                 e.initCause( error );
184                 throw e;
185             }
186 
187             return result;
188         }
189         finally
190         {
191             Thread.currentThread().setContextClassLoader( oldContextClassLoader );
192         }
193     }
194 
195     private DependencyResolutionResult resolveDependencies( MavenProject project, RepositorySystemSession session )
196     {
197         DependencyResolutionResult resolutionResult;
198 
199         try
200         {
201             DefaultDependencyResolutionRequest resolution = new DefaultDependencyResolutionRequest( project, session );
202             resolutionResult = dependencyResolver.resolve( resolution );
203         }
204         catch ( DependencyResolutionException e )
205         {
206             resolutionResult = e.getResult();
207         }
208 
209         Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
210         if ( resolutionResult.getDependencyGraph() != null )
211         {
212             RepositoryUtils.toArtifacts( artifacts, resolutionResult.getDependencyGraph().getChildren(),
213                                          Collections.singletonList( project.getArtifact().getId() ), null );
214 
215             // Maven 2.x quirk: an artifact always points at the local repo, regardless whether resolved or not
216             LocalRepositoryManager lrm = session.getLocalRepositoryManager();
217             for ( Artifact artifact : artifacts )
218             {
219                 if ( !artifact.isResolved() )
220                 {
221                     String path = lrm.getPathForLocalArtifact( RepositoryUtils.toArtifact( artifact ) );
222                     artifact.setFile( new File( lrm.getRepository().getBasedir(), path ) );
223                 }
224             }
225         }
226         project.setResolvedArtifacts( artifacts );
227         project.setArtifacts( artifacts );
228 
229         return resolutionResult;
230     }
231 
232     private List<String> getProfileIds( List<Profile> profiles )
233     {
234         List<String> ids = new ArrayList<String>( profiles.size() );
235 
236         for ( Profile profile : profiles )
237         {
238             ids.add( profile.getId() );
239         }
240 
241         return ids;
242     }
243 
244     private ModelBuildingRequest getModelBuildingRequest( InternalConfig config )
245     {
246         ProjectBuildingRequest configuration = config.request;
247 
248         ModelBuildingRequest request = new DefaultModelBuildingRequest();
249 
250         RequestTrace trace = RequestTrace.newChild( null, configuration ).newChild( request );
251 
252         ModelResolver resolver =
253             new ProjectModelResolver( config.session, trace, repoSystem, repositoryManager, config.repositories,
254                                       configuration.getRepositoryMerging(), config.modelPool );
255 
256         request.setValidationLevel( configuration.getValidationLevel() );
257         request.setProcessPlugins( configuration.isProcessPlugins() );
258         request.setProfiles( configuration.getProfiles() );
259         request.setActiveProfileIds( configuration.getActiveProfileIds() );
260         request.setInactiveProfileIds( configuration.getInactiveProfileIds() );
261         request.setSystemProperties( configuration.getSystemProperties() );
262         request.setUserProperties( configuration.getUserProperties() );
263         request.setBuildStartTime( configuration.getBuildStartTime() );
264         request.setModelResolver( resolver );
265         request.setModelCache( new ReactorModelCache() );
266 
267         return request;
268     }
269 
270     public ProjectBuildingResult build( Artifact artifact, ProjectBuildingRequest request )
271         throws ProjectBuildingException
272     {
273         return build( artifact, false, request );
274     }
275 
276     public ProjectBuildingResult build( Artifact artifact, boolean allowStubModel, ProjectBuildingRequest request )
277         throws ProjectBuildingException
278     {
279         org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact( artifact );
280         pomArtifact = ArtifactDescriptorUtils.toPomArtifact( pomArtifact );
281 
282         InternalConfig config = new InternalConfig( request, null );
283 
284         boolean localProject;
285 
286         if ( request.isResolveVersionRanges() )
287         {
288             VersionRangeRequest versionRangeRequest = new VersionRangeRequest( pomArtifact, config.repositories, null );
289 
290             try
291             {
292                 VersionRangeResult versionRangeResult =
293                     repoSystem.resolveVersionRange( config.session, versionRangeRequest );
294 
295                 if ( versionRangeResult.getHighestVersion() == null )
296                 {
297                     throw new ProjectBuildingException(
298                         artifact.getId(), "Error resolving project artifact: No versions matched the requested range",
299                         (Throwable) null );
300 
301                 }
302 
303                 if ( versionRangeResult.getVersionConstraint() != null
304                          && versionRangeResult.getVersionConstraint().getRange() != null
305                          && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
306                 {
307                     throw new ProjectBuildingException(
308                         artifact.getId(),
309                         "Error resolving project artifact: The requested version range does not specify an upper bound",
310                         (Throwable) null );
311 
312                 }
313 
314                 pomArtifact = pomArtifact.setVersion( versionRangeResult.getHighestVersion().toString() );
315             }
316             catch ( VersionRangeResolutionException e )
317             {
318                 throw new ProjectBuildingException(
319                     artifact.getId(), "Error resolving project artifact: " + e.getMessage(), e );
320 
321             }
322         }
323 
324         try
325         {
326             ArtifactRequest pomRequest = new ArtifactRequest();
327             pomRequest.setArtifact( pomArtifact );
328             pomRequest.setRepositories( config.repositories );
329             ArtifactResult pomResult = repoSystem.resolveArtifact( config.session, pomRequest );
330 
331             pomArtifact = pomResult.getArtifact();
332             localProject = pomResult.getRepository() instanceof WorkspaceRepository;
333         }
334         catch ( org.eclipse.aether.resolution.ArtifactResolutionException e )
335         {
336             if ( e.getResults().get( 0 ).isMissing() && allowStubModel )
337             {
338                 return build( null, createStubModelSource( artifact ), config );
339             }
340             throw new ProjectBuildingException( artifact.getId(),
341                                                 "Error resolving project artifact: " + e.getMessage(), e );
342         }
343 
344         File pomFile = pomArtifact.getFile();
345 
346         if ( "pom".equals( artifact.getType() ) )
347         {
348             artifact.selectVersion( pomArtifact.getVersion() );
349             artifact.setFile( pomFile );
350             artifact.setResolved( true );
351         }
352 
353         return build( localProject ? pomFile : null, new FileModelSource( pomFile ), config );
354     }
355 
356     private ModelSource createStubModelSource( Artifact artifact )
357     {
358         StringBuilder buffer = new StringBuilder( 1024 );
359 
360         buffer.append( "<?xml version='1.0'?>" );
361         buffer.append( "<project>" );
362         buffer.append( "<modelVersion>4.0.0</modelVersion>" );
363         buffer.append( "<groupId>" ).append( artifact.getGroupId() ).append( "</groupId>" );
364         buffer.append( "<artifactId>" ).append( artifact.getArtifactId() ).append( "</artifactId>" );
365         buffer.append( "<version>" ).append( artifact.getBaseVersion() ).append( "</version>" );
366         buffer.append( "<packaging>" ).append( artifact.getType() ).append( "</packaging>" );
367         buffer.append( "</project>" );
368 
369         return new StringModelSource( buffer, artifact.getId() );
370     }
371 
372     public List<ProjectBuildingResult> build( List<File> pomFiles, boolean recursive, ProjectBuildingRequest request )
373         throws ProjectBuildingException
374     {
375         List<ProjectBuildingResult> results = new ArrayList<ProjectBuildingResult>();
376 
377         List<InterimResult> interimResults = new ArrayList<InterimResult>();
378 
379         ReactorModelPool modelPool = new ReactorModelPool();
380 
381         InternalConfig config = new InternalConfig( request, modelPool );
382 
383         Map<String, MavenProject> projectIndex = new HashMap<String, MavenProject>( 256 );
384 
385         boolean noErrors =
386             build( results, interimResults, projectIndex, pomFiles, new LinkedHashSet<File>(), true, recursive, config );
387 
388         populateReactorModelPool( modelPool, interimResults );
389 
390         ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
391 
392         try
393         {
394             noErrors =
395                 build( results, new ArrayList<MavenProject>(), projectIndex, interimResults, request,
396                        new HashMap<File, Boolean>() ) && noErrors;
397         }
398         finally
399         {
400             Thread.currentThread().setContextClassLoader( oldContextClassLoader );
401         }
402 
403         if ( !noErrors )
404         {
405             throw new ProjectBuildingException( results );
406         }
407 
408         return results;
409     }
410 
411     private boolean build( List<ProjectBuildingResult> results, List<InterimResult> interimResults,
412                            Map<String, MavenProject> projectIndex, List<File> pomFiles, Set<File> aggregatorFiles,
413                            boolean isRoot, boolean recursive, InternalConfig config )
414     {
415         boolean noErrors = true;
416 
417         for ( File pomFile : pomFiles )
418         {
419             aggregatorFiles.add( pomFile );
420 
421             if ( !build( results, interimResults, projectIndex, pomFile, aggregatorFiles, isRoot, recursive, config ) )
422             {
423                 noErrors = false;
424             }
425 
426             aggregatorFiles.remove( pomFile );
427         }
428 
429         return noErrors;
430     }
431 
432     private boolean build( List<ProjectBuildingResult> results, List<InterimResult> interimResults,
433                            Map<String, MavenProject> projectIndex, File pomFile, Set<File> aggregatorFiles,
434                            boolean isRoot, boolean recursive, InternalConfig config )
435     {
436         boolean noErrors = true;
437 
438         ModelBuildingRequest request = getModelBuildingRequest( config );
439 
440         MavenProject project = new MavenProject( repositorySystem, this, config.request, logger );
441 
442         request.setPomFile( pomFile );
443         request.setTwoPhaseBuilding( true );
444         request.setLocationTracking( true );
445 
446         DefaultModelBuildingListener listener =
447             new DefaultModelBuildingListener( project, projectBuildingHelper, config.request );
448         request.setModelBuildingListener( listener );
449 
450         try
451         {
452             ModelBuildingResult result = modelBuilder.build( request );
453 
454             Model model = result.getEffectiveModel();
455 
456             projectIndex.put( result.getModelIds().get( 0 ), project );
457 
458             InterimResult interimResult = new InterimResult( pomFile, request, result, listener, isRoot );
459             interimResults.add( interimResult );
460 
461             if ( recursive && !model.getModules().isEmpty() )
462             {
463                 File basedir = pomFile.getParentFile();
464 
465                 List<File> moduleFiles = new ArrayList<File>();
466 
467                 for ( String module : model.getModules() )
468                 {
469                     if ( StringUtils.isEmpty( module ) )
470                     {
471                         continue;
472                     }
473 
474                     module = module.replace( '\\', File.separatorChar ).replace( '/', File.separatorChar );
475 
476                     File moduleFile = new File( basedir, module );
477 
478                     if ( moduleFile.isDirectory() )
479                     {
480                         moduleFile = modelProcessor.locatePom( moduleFile );
481                     }
482 
483                     if ( !moduleFile.isFile() )
484                     {
485                         ModelProblem problem =
486                             new DefaultModelProblem( "Child module " + moduleFile + " of " + pomFile
487                                 + " does not exist", ModelProblem.Severity.ERROR, ModelProblem.Version.BASE, model, -1, -1, null );
488                         result.getProblems().add( problem );
489 
490                         noErrors = false;
491 
492                         continue;
493                     }
494 
495                     if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
496                     {
497                         // we don't canonicalize on unix to avoid interfering with symlinks
498                         try
499                         {
500                             moduleFile = moduleFile.getCanonicalFile();
501                         }
502                         catch ( IOException e )
503                         {
504                             moduleFile = moduleFile.getAbsoluteFile();
505                         }
506                     }
507                     else
508                     {
509                         moduleFile = new File( moduleFile.toURI().normalize() );
510                     }
511 
512                     if ( aggregatorFiles.contains( moduleFile ) )
513                     {
514                         StringBuilder buffer = new StringBuilder( 256 );
515                         for ( File aggregatorFile : aggregatorFiles )
516                         {
517                             buffer.append( aggregatorFile ).append( " -> " );
518                         }
519                         buffer.append( moduleFile );
520 
521                         ModelProblem problem =
522                             new DefaultModelProblem( "Child module " + moduleFile + " of " + pomFile
523                                 + " forms aggregation cycle " + buffer, ModelProblem.Severity.ERROR, ModelProblem.Version.BASE, model, -1, -1,
524                                                      null );
525                         result.getProblems().add( problem );
526 
527                         noErrors = false;
528 
529                         continue;
530                     }
531 
532                     moduleFiles.add( moduleFile );
533                 }
534 
535                 interimResult.modules = new ArrayList<InterimResult>();
536 
537                 if ( !build( results, interimResult.modules, projectIndex, moduleFiles, aggregatorFiles, false,
538                              recursive, config ) )
539                 {
540                     noErrors = false;
541                 }
542             }
543         }
544         catch ( ModelBuildingException e )
545         {
546             results.add( new DefaultProjectBuildingResult( e.getModelId(), pomFile, e.getProblems() ) );
547 
548             noErrors = false;
549         }
550 
551         return noErrors;
552     }
553 
554     static class InterimResult
555     {
556 
557         File pomFile;
558 
559         ModelBuildingRequest request;
560 
561         ModelBuildingResult result;
562 
563         DefaultModelBuildingListener listener;
564 
565         boolean root;
566 
567         List<InterimResult> modules = Collections.emptyList();
568 
569         InterimResult( File pomFile, ModelBuildingRequest request, ModelBuildingResult result,
570                        DefaultModelBuildingListener listener, boolean root )
571         {
572             this.pomFile = pomFile;
573             this.request = request;
574             this.result = result;
575             this.listener = listener;
576             this.root = root;
577         }
578 
579     }
580 
581     private void populateReactorModelPool( ReactorModelPool reactorModelPool, List<InterimResult> interimResults )
582     {
583         for ( InterimResult interimResult : interimResults )
584         {
585             Model model = interimResult.result.getEffectiveModel();
586             reactorModelPool.put( model.getGroupId(), model.getArtifactId(), model.getVersion(), model.getPomFile() );
587 
588             populateReactorModelPool( reactorModelPool, interimResult.modules );
589         }
590     }
591 
592     private boolean build( List<ProjectBuildingResult> results, List<MavenProject> projects,
593                            Map<String, MavenProject> projectIndex, List<InterimResult> interimResults,
594                            ProjectBuildingRequest request, Map<File, Boolean> profilesXmls )
595     {
596         boolean noErrors = true;
597 
598         for ( InterimResult interimResult : interimResults )
599         {
600             try
601             {
602                 ModelBuildingResult result = modelBuilder.build( interimResult.request, interimResult.result );
603 
604                 MavenProject project = interimResult.listener.getProject();
605                 initProject( project, projectIndex, result, profilesXmls );
606 
607                 List<MavenProject> modules = new ArrayList<MavenProject>();
608                 noErrors =
609                     build( results, modules, projectIndex, interimResult.modules, request, profilesXmls ) && noErrors;
610 
611                 projects.addAll( modules );
612                 projects.add( project );
613 
614                 project.setExecutionRoot( interimResult.root );
615                 project.setCollectedProjects( modules );
616 
617                 results.add( new DefaultProjectBuildingResult( project, result.getProblems(), null ) );
618             }
619             catch ( ModelBuildingException e )
620             {
621                 results.add( new DefaultProjectBuildingResult( e.getModelId(), interimResult.pomFile, e.getProblems() ) );
622 
623                 noErrors = false;
624             }
625         }
626 
627         return noErrors;
628     }
629 
630     private void initProject( MavenProject project, Map<String, MavenProject> projects, ModelBuildingResult result,
631                               Map<File, Boolean> profilesXmls )
632     {
633         Model model = result.getEffectiveModel();
634 
635         project.setModel( model );
636         project.setOriginalModel( result.getRawModel() );
637 
638         project.setFile( model.getPomFile() );
639 
640         File parentPomFile = result.getRawModel( result.getModelIds().get( 1 ) ).getPomFile();
641         project.setParentFile( parentPomFile );
642 
643         project.setParent( projects.get( result.getModelIds().get( 1 ) ) );
644 
645         Artifact projectArtifact =
646             repositorySystem.createArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), null,
647                                              project.getPackaging() );
648         project.setArtifact( projectArtifact );
649 
650         if ( project.getFile() != null )
651         {
652             Build build = project.getBuild();
653             project.addScriptSourceRoot( build.getScriptSourceDirectory() );
654             project.addCompileSourceRoot( build.getSourceDirectory() );
655             project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
656         }
657 
658         List<Profile> activeProfiles = new ArrayList<Profile>();
659         activeProfiles.addAll( result.getActivePomProfiles( result.getModelIds().get( 0 ) ) );
660         activeProfiles.addAll( result.getActiveExternalProfiles() );
661         project.setActiveProfiles( activeProfiles );
662 
663         project.setInjectedProfileIds( "external", getProfileIds( result.getActiveExternalProfiles() ) );
664         for ( String modelId : result.getModelIds() )
665         {
666             project.setInjectedProfileIds( modelId, getProfileIds( result.getActivePomProfiles( modelId ) ) );
667         }
668 
669         String modelId = findProfilesXml( result, profilesXmls );
670         if ( modelId != null )
671         {
672             ModelProblem problem =
673                 new DefaultModelProblem( "Detected profiles.xml alongside " + modelId
674                     + ", this file is no longer supported and was ignored" + ", please use the settings.xml instead",
675                                          ModelProblem.Severity.WARNING, ModelProblem.Version.V30, model, -1, -1, null );
676             result.getProblems().add( problem );
677         }
678     }
679 
680     private String findProfilesXml( ModelBuildingResult result, Map<File, Boolean> profilesXmls )
681     {
682         for ( String modelId : result.getModelIds() )
683         {
684             Model model = result.getRawModel( modelId );
685 
686             File basedir = model.getProjectDirectory();
687             if ( basedir == null )
688             {
689                 break;
690             }
691 
692             Boolean profilesXml = profilesXmls.get( basedir );
693             if ( profilesXml == null )
694             {
695                 profilesXml = new File( basedir, "profiles.xml" ).exists();
696                 profilesXmls.put( basedir, profilesXml );
697             }
698             if ( profilesXml )
699             {
700                 return modelId;
701             }
702         }
703 
704         return null;
705     }
706 
707     class InternalConfig
708     {
709 
710         public final ProjectBuildingRequest request;
711 
712         public final RepositorySystemSession session;
713 
714         public final List<RemoteRepository> repositories;
715 
716         public final ReactorModelPool modelPool;
717 
718         InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool )
719         {
720             this.request = request;
721             this.modelPool = modelPool;
722             session =
723                 LegacyLocalRepositoryManager.overlay( request.getLocalRepository(), request.getRepositorySession(),
724                                                       repoSystem );
725             repositories = RepositoryUtils.toRepos( request.getRemoteRepositories() );
726         }
727 
728     }
729 
730 }