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.building;
20  
21  import java.io.PrintWriter;
22  import java.io.StringWriter;
23  import java.util.Collections;
24  import java.util.List;
25  import org.apache.maven.model.Model;
26  
27  /**
28   * Signals one ore more errors during model building. The model builder tries to collect as many problems as possible
29   * before eventually failing to provide callers with rich error information. Use {@link #getProblems()} to query the
30   * details of the failure.
31   *
32   * @author Benjamin Bentmann
33   */
34  public class ModelBuildingException extends Exception {
35  
36      private final ModelBuildingResult result;
37  
38      /**
39       * Creates a new exception with the specified problems.
40       *
41       * @param model The model that could not be built, may be {@code null}.
42       * @param modelId The identifier of the model that could not be built, may be {@code null}.
43       * @param problems The problems that cause this exception, may be {@code null}.
44       * @deprecated Use {@link #ModelBuildingException(ModelBuildingResult)} instead.
45       */
46      @Deprecated
47      public ModelBuildingException(Model model, String modelId, List<ModelProblem> problems) {
48          super(toMessage(modelId, problems));
49  
50          if (model != null) {
51              DefaultModelBuildingResult tmp = new DefaultModelBuildingResult();
52              if (modelId == null) {
53                  modelId = "";
54              }
55              tmp.addModelId(modelId);
56              tmp.setRawModel(modelId, model);
57              tmp.setProblems(problems);
58              result = tmp;
59          } else {
60              result = null;
61          }
62      }
63  
64      /**
65       * Creates a new exception from the specified interim result and its associated problems.
66       *
67       * @param result The interim result, may be {@code null}.
68       */
69      public ModelBuildingException(ModelBuildingResult result) {
70          super(toMessage(result));
71          this.result = result;
72      }
73  
74      /**
75       * Gets the interim result of the model building up to the point where it failed.
76       *
77       * @return The interim model building result or {@code null} if not available.
78       */
79      public ModelBuildingResult getResult() {
80          return result;
81      }
82  
83      /**
84       * Gets the model that could not be built properly.
85       *
86       * @return The erroneous model or {@code null} if not available.
87       */
88      public Model getModel() {
89          if (result == null) {
90              return null;
91          }
92          if (result.getEffectiveModel() != null) {
93              return result.getEffectiveModel();
94          }
95          return result.getRawModel();
96      }
97  
98      /**
99       * Gets the identifier of the POM whose effective model could not be built. The general format of the identifier is
100      * {@code <groupId>:<artifactId>:<version>} but some of these coordinates may still be unknown at the point the
101      * exception is thrown so this information is merely meant to assist the user.
102      *
103      * @return The identifier of the POM or an empty string if not known, never {@code null}.
104      */
105     public String getModelId() {
106         if (result == null || result.getModelIds().isEmpty()) {
107             return "";
108         }
109         return result.getModelIds().get(0);
110     }
111 
112     /**
113      * Gets the problems that caused this exception.
114      *
115      * @return The problems that caused this exception, never {@code null}.
116      */
117     public List<ModelProblem> getProblems() {
118         if (result == null) {
119             return Collections.emptyList();
120         }
121         return Collections.unmodifiableList(result.getProblems());
122     }
123 
124     private static String toMessage(ModelBuildingResult result) {
125         if (result != null && !result.getModelIds().isEmpty()) {
126             return toMessage(result.getModelIds().get(0), result.getProblems());
127         }
128         return null;
129     }
130 
131     private static String toMessage(String modelId, List<ModelProblem> problems) {
132         StringWriter buffer = new StringWriter(1024);
133 
134         PrintWriter writer = new PrintWriter(buffer);
135 
136         writer.print(problems.size());
137         writer.print((problems.size() == 1) ? " problem was " : " problems were ");
138         writer.print("encountered while building the effective model");
139         if (modelId != null && modelId.length() > 0) {
140             writer.print(" for ");
141             writer.print(modelId);
142         }
143         writer.println();
144 
145         for (ModelProblem problem : problems) {
146             writer.print("[");
147             writer.print(problem.getSeverity());
148             writer.print("] ");
149             writer.print(problem.getMessage());
150             String location = ModelProblemUtils.formatLocation(problem, modelId);
151             if (!location.isEmpty()) {
152                 writer.print(" @ ");
153                 writer.println(location);
154             }
155         }
156 
157         return buffer.toString();
158     }
159 }