1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.toolchain.building;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.io.IOException;
26  import java.io.StringReader;
27  import java.io.StringWriter;
28  import java.util.Collections;
29  import java.util.List;
30  import java.util.Map;
31  
32  import org.apache.maven.building.Problem;
33  import org.apache.maven.building.ProblemCollector;
34  import org.apache.maven.building.ProblemCollectorFactory;
35  import org.apache.maven.building.Source;
36  import org.apache.maven.toolchain.io.ToolchainsParseException;
37  import org.apache.maven.toolchain.io.ToolchainsReader;
38  import org.apache.maven.toolchain.io.ToolchainsWriter;
39  import org.apache.maven.toolchain.merge.MavenToolchainMerger;
40  import org.apache.maven.toolchain.model.PersistedToolchains;
41  import org.apache.maven.toolchain.model.TrackableBase;
42  import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
43  import org.codehaus.plexus.interpolation.InterpolationException;
44  import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
45  import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
46  
47  
48  
49  
50  
51  
52  @Named
53  @Singleton
54  @Deprecated(since = "4.0.0")
55  public class DefaultToolchainsBuilder implements ToolchainsBuilder {
56      private MavenToolchainMerger toolchainsMerger = new MavenToolchainMerger();
57  
58      @Inject
59      private ToolchainsWriter toolchainsWriter;
60  
61      @Inject
62      private ToolchainsReader toolchainsReader;
63  
64      @Override
65      public ToolchainsBuildingResult build(ToolchainsBuildingRequest request) throws ToolchainsBuildingException {
66          ProblemCollector problems = ProblemCollectorFactory.newInstance(null);
67  
68          PersistedToolchains globalToolchains = readToolchains(request.getGlobalToolchainsSource(), request, problems);
69  
70          PersistedToolchains userToolchains = readToolchains(request.getUserToolchainsSource(), request, problems);
71  
72          toolchainsMerger.merge(userToolchains, globalToolchains, TrackableBase.GLOBAL_LEVEL);
73  
74          problems.setSource("");
75  
76          userToolchains = interpolate(userToolchains, problems);
77  
78          if (hasErrors(problems.getProblems())) {
79              throw new ToolchainsBuildingException(problems.getProblems());
80          }
81  
82          return new DefaultToolchainsBuildingResult(userToolchains, problems.getProblems());
83      }
84  
85      private PersistedToolchains interpolate(PersistedToolchains toolchains, ProblemCollector problems) {
86  
87          StringWriter stringWriter = new StringWriter(1024 * 4);
88          try {
89              toolchainsWriter.write(stringWriter, null, toolchains);
90          } catch (IOException e) {
91              throw new IllegalStateException("Failed to serialize toolchains to memory", e);
92          }
93  
94          String serializedToolchains = stringWriter.toString();
95  
96          RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
97  
98          try {
99              interpolator.addValueSource(new EnvarBasedValueSource());
100         } catch (IOException e) {
101             problems.add(
102                     Problem.Severity.WARNING,
103                     "Failed to use environment variables for interpolation: " + e.getMessage(),
104                     -1,
105                     -1,
106                     e);
107         }
108 
109         interpolator.addPostProcessor(new InterpolationPostProcessor() {
110             @Override
111             public Object execute(String expression, Object value) {
112                 if (value != null) {
113                     
114                     value = value.toString()
115                             .replace("&", "&")
116                             .replace("<", "<")
117                             .replace(">", ">");
118                     return value;
119                 }
120                 return null;
121             }
122         });
123 
124         try {
125             serializedToolchains = interpolator.interpolate(serializedToolchains);
126         } catch (InterpolationException e) {
127             problems.add(Problem.Severity.ERROR, "Failed to interpolate toolchains: " + e.getMessage(), -1, -1, e);
128             return toolchains;
129         }
130 
131         PersistedToolchains result;
132         try {
133             Map<String, ?> options = Collections.singletonMap(ToolchainsReader.IS_STRICT, Boolean.FALSE);
134 
135             result = toolchainsReader.read(new StringReader(serializedToolchains), options);
136         } catch (IOException e) {
137             problems.add(Problem.Severity.ERROR, "Failed to interpolate toolchains: " + e.getMessage(), -1, -1, e);
138             return toolchains;
139         }
140 
141         return result;
142     }
143 
144     private PersistedToolchains readToolchains(
145             Source toolchainsSource, ToolchainsBuildingRequest request, ProblemCollector problems) {
146         if (toolchainsSource == null) {
147             return new PersistedToolchains();
148         }
149 
150         PersistedToolchains toolchains;
151 
152         try {
153             Map<String, ?> options = Collections.singletonMap(ToolchainsReader.IS_STRICT, Boolean.TRUE);
154 
155             try {
156                 toolchains = toolchainsReader.read(toolchainsSource.getInputStream(), options);
157             } catch (ToolchainsParseException e) {
158                 options = Collections.singletonMap(ToolchainsReader.IS_STRICT, Boolean.FALSE);
159 
160                 toolchains = toolchainsReader.read(toolchainsSource.getInputStream(), options);
161 
162                 problems.add(Problem.Severity.WARNING, e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e);
163             }
164         } catch (ToolchainsParseException e) {
165             problems.add(
166                     Problem.Severity.FATAL,
167                     "Non-parseable toolchains " + toolchainsSource.getLocation() + ": " + e.getMessage(),
168                     e.getLineNumber(),
169                     e.getColumnNumber(),
170                     e);
171             return new PersistedToolchains();
172         } catch (IOException e) {
173             problems.add(
174                     Problem.Severity.FATAL,
175                     "Non-readable toolchains " + toolchainsSource.getLocation() + ": " + e.getMessage(),
176                     -1,
177                     -1,
178                     e);
179             return new PersistedToolchains();
180         }
181 
182         return toolchains;
183     }
184 
185     private boolean hasErrors(List<Problem> problems) {
186         if (problems != null) {
187             for (Problem problem : problems) {
188                 if (Problem.Severity.ERROR.compareTo(problem.getSeverity()) >= 0) {
189                     return true;
190                 }
191             }
192         }
193 
194         return false;
195     }
196 }