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.project;
20  
21  import java.nio.file.Path;
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import org.apache.maven.api.ProjectScope;
26  import org.apache.maven.api.SourceRoot;
27  import org.apache.maven.impl.DefaultSourceRoot;
28  import org.apache.maven.model.Resource;
29  
30  /**
31   * A Resource wrapper that maintains a connection to the underlying project model.
32   * When includes/excludes are modified, the changes are propagated back to the project's SourceRoots.
33   */
34  @SuppressWarnings("deprecation")
35  class ConnectedResource extends Resource {
36      private final SourceRoot originalSourceRoot;
37      private final ProjectScope scope;
38      private final MavenProject project;
39  
40      ConnectedResource(SourceRoot sourceRoot, ProjectScope scope, MavenProject project) {
41          super(org.apache.maven.api.model.Resource.newBuilder()
42                  .directory(sourceRoot.directory().toString())
43                  .includes(sourceRoot.includes())
44                  .excludes(sourceRoot.excludes())
45                  .filtering(Boolean.toString(sourceRoot.stringFiltering()))
46                  .targetPath(sourceRoot.targetPath().map(Path::toString).orElse(null))
47                  .build());
48          this.originalSourceRoot = sourceRoot;
49          this.scope = scope;
50          this.project = project;
51      }
52  
53      @Override
54      public void addInclude(String include) {
55          // Update the underlying Resource model
56          super.addInclude(include);
57  
58          // Update the project's SourceRoots
59          updateProjectSourceRoot();
60      }
61  
62      @Override
63      public void removeInclude(String include) {
64          // Update the underlying Resource model
65          super.removeInclude(include);
66  
67          // Update the project's SourceRoots
68          updateProjectSourceRoot();
69      }
70  
71      @Override
72      public void addExclude(String exclude) {
73          // Update the underlying Resource model
74          super.addExclude(exclude);
75  
76          // Update the project's SourceRoots
77          updateProjectSourceRoot();
78      }
79  
80      @Override
81      public void removeExclude(String exclude) {
82          // Update the underlying Resource model
83          super.removeExclude(exclude);
84  
85          // Update the project's SourceRoots
86          updateProjectSourceRoot();
87      }
88  
89      @Override
90      public void setIncludes(List<String> includes) {
91          // Update the underlying Resource model
92          super.setIncludes(includes);
93  
94          // Update the project's SourceRoots
95          updateProjectSourceRoot();
96      }
97  
98      @Override
99      public void setExcludes(List<String> excludes) {
100         // Update the underlying Resource model
101         super.setExcludes(excludes);
102 
103         // Update the project's SourceRoots
104         updateProjectSourceRoot();
105     }
106 
107     private void updateProjectSourceRoot() {
108         // Convert the LinkedHashSet to a List to maintain order
109         List<SourceRoot> sourcesList = new ArrayList<>(project.sources);
110 
111         // Find the index of the original SourceRoot
112         int index = -1;
113         for (int i = 0; i < sourcesList.size(); i++) {
114             SourceRoot source = sourcesList.get(i);
115             if (source.scope() == originalSourceRoot.scope()
116                     && source.language() == originalSourceRoot.language()
117                     && source.directory().equals(originalSourceRoot.directory())) {
118                 index = i;
119                 break;
120             }
121         }
122 
123         if (index >= 0) {
124             // Replace the SourceRoot at the same position
125             SourceRoot newSourceRoot = new DefaultSourceRoot(project.getBaseDirectory(), scope, this.getDelegate());
126             sourcesList.set(index, newSourceRoot);
127 
128             // Update the project's sources, preserving order
129             project.sources.clear();
130             project.sources.addAll(sourcesList);
131         }
132     }
133 }