View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.model.path;
20  
21  import java.io.File;
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.Objects;
25  import java.util.function.Function;
26  import javax.inject.Inject;
27  import javax.inject.Named;
28  import javax.inject.Singleton;
29  import org.apache.maven.api.model.Build;
30  import org.apache.maven.api.model.Model;
31  import org.apache.maven.api.model.Reporting;
32  import org.apache.maven.api.model.Resource;
33  import org.apache.maven.model.building.ModelBuildingRequest;
34  
35  /**
36   * Resolves relative paths within a model against a specific base directory.
37   *
38   * @author Benjamin Bentmann
39   */
40  @Named
41  @Singleton
42  public class DefaultModelPathTranslator implements ModelPathTranslator {
43  
44      private final PathTranslator pathTranslator;
45  
46      @Inject
47      public DefaultModelPathTranslator(PathTranslator pathTranslator) {
48          this.pathTranslator = pathTranslator;
49      }
50  
51      @Override
52      public void alignToBaseDirectory(org.apache.maven.model.Model modelV3, File basedir, ModelBuildingRequest request) {
53          if (modelV3 == null || basedir == null) {
54              return;
55          }
56  
57          Model model = modelV3.getDelegate();
58          Build build = model.getBuild();
59          Build newBuild = null;
60          if (build != null) {
61              newBuild = Build.newBuilder(build)
62                      .directory(alignToBaseDirectory(build.getDirectory(), basedir))
63                      .sourceDirectory(alignToBaseDirectory(build.getSourceDirectory(), basedir))
64                      .testSourceDirectory(alignToBaseDirectory(build.getTestSourceDirectory(), basedir))
65                      .scriptSourceDirectory(alignToBaseDirectory(build.getScriptSourceDirectory(), basedir))
66                      .resources(map(build.getResources(), r -> alignToBaseDirectory(r, basedir)))
67                      .testResources(map(build.getTestResources(), r -> alignToBaseDirectory(r, basedir)))
68                      .filters(map(build.getFilters(), s -> alignToBaseDirectory(s, basedir)))
69                      .outputDirectory(alignToBaseDirectory(build.getOutputDirectory(), basedir))
70                      .testOutputDirectory(alignToBaseDirectory(build.getTestOutputDirectory(), basedir))
71                      .build();
72          }
73  
74          Reporting reporting = model.getReporting();
75          Reporting newReporting = null;
76          if (reporting != null) {
77              newReporting = Reporting.newBuilder(reporting)
78                      .outputDirectory(alignToBaseDirectory(reporting.getOutputDirectory(), basedir))
79                      .build();
80          }
81          if (newBuild != build || newReporting != reporting) {
82              modelV3.update(Model.newBuilder(model)
83                      .build(newBuild)
84                      .reporting(newReporting)
85                      .build());
86          }
87      }
88  
89      private <T> List<T> map(List<T> resources, Function<T, T> mapper) {
90          List<T> newResources = null;
91          if (resources != null) {
92              for (int i = 0; i < resources.size(); i++) {
93                  T resource = resources.get(i);
94                  T newResource = mapper.apply(resource);
95                  if (newResource != null) {
96                      if (newResources == null) {
97                          newResources = new ArrayList<>(resources);
98                      }
99                      newResources.set(i, newResource);
100                 }
101             }
102         }
103         return newResources;
104     }
105 
106     private Resource alignToBaseDirectory(Resource resource, File basedir) {
107         if (resource != null) {
108             String newDir = alignToBaseDirectory(resource.getDirectory(), basedir);
109             if (newDir != null) {
110                 return resource.withDirectory(newDir);
111             }
112         }
113         return resource;
114     }
115 
116     private String alignToBaseDirectory(String path, File basedir) {
117         String newPath = pathTranslator.alignToBaseDirectory(path, basedir);
118         return Objects.equals(path, newPath) ? null : newPath;
119     }
120 }