View Javadoc
1   package org.apache.maven.model.building;
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 static java.util.Collections.singleton;
23  import static org.apache.maven.model.building.ModelProblem.Severity.ERROR;
24  import static org.apache.maven.model.building.ModelProblem.Severity.FATAL;
25  
26  import java.util.ArrayList;
27  import java.util.Collection;
28  import java.util.Collections;
29  import java.util.List;
30  
31  /**
32   * There are various forms of results that are represented by this class:
33   * <ol>
34   * <li>success - in which case only the model field is set
35   * <li>success with warnings - model field + non-error model problems
36   * <li>error - no model, but diagnostics
37   * <li>error - (partial) model and diagnostics
38   * </ol>
39   * Could encode these variants as subclasses, but kept in one for now
40   *
41   * @author bbusjaeger
42   * @param <T>
43   */
44  public class Result<T>
45  {
46  
47      /**
48       * Success without warnings
49       *
50       * @param model
51       */
52      public static <T> Result<T> success( T model )
53      {
54          return success( model, Collections.<ModelProblem>emptyList() );
55      }
56  
57      /**
58       * Success with warnings
59       *
60       * @param model
61       * @param problems
62       */
63      public static <T> Result<T> success( T model, Iterable<? extends ModelProblem> problems )
64      {
65          assert !hasErrors( problems );
66          return new Result<>( false, model, problems );
67      }
68  
69      /**
70       * Success with warnings
71       *
72       * @param model
73       * @param results
74       */
75      public static <T> Result<T> success( T model, Result<?>... results )
76      {
77          final List<ModelProblem> problemsList = new ArrayList<>();
78  
79          for ( Result<?> result1 : results )
80          {
81              for ( ModelProblem modelProblem : result1.getProblems() )
82              {
83                  problemsList.add( modelProblem );
84              }
85          }
86  
87          return success( model, problemsList );
88      }
89  
90      /**
91       * Error with problems describing the cause
92       *
93       * @param problems
94       */
95      public static <T> Result<T> error( Iterable<? extends ModelProblem> problems )
96      {
97          return error( null, problems );
98      }
99  
100     public static <T> Result<T> error( T model )
101     {
102         return error( model, Collections.<ModelProblem>emptyList() );
103     }
104 
105     public static <T> Result<T> error( Result<?> result )
106     {
107         return error( result.getProblems() );
108     }
109 
110     public static <T> Result<T> error( Result<?>... results )
111     {
112         final List<ModelProblem> problemsList = new ArrayList<>( );
113 
114         for ( Result<?> result1 : results )
115         {
116             for ( ModelProblem modelProblem : result1.getProblems( ) )
117             {
118                 problemsList.add( modelProblem );
119             }
120         }
121 
122         return error( problemsList );
123     }
124 
125     /**
126      * Error with partial result and problems describing the cause
127      *
128      * @param model
129      * @param problems
130      */
131     public static <T> Result<T> error( T model, Iterable<? extends ModelProblem> problems )
132     {
133         return new Result<>( true, model, problems );
134     }
135 
136     /**
137      * New result - determine whether error or success by checking problems for errors
138      *
139      * @param model
140      * @param problems
141      */
142     public static <T> Result<T> newResult( T model, Iterable<? extends ModelProblem> problems )
143     {
144         return new Result<>( hasErrors( problems ), model, problems );
145     }
146 
147     /**
148      * New result consisting of given result and new problem. Convenience for newResult(result.get(),
149      * concat(result.getProblems(),problems)).
150      *
151      * @param result
152      * @param problem
153      */
154     public static <T> Result<T> addProblem( Result<T> result, ModelProblem problem )
155     {
156         return addProblems( result, singleton( problem ) );
157     }
158 
159     /**
160      * New result that includes the given
161      *
162      * @param result
163      * @param problems
164      */
165     public static <T> Result<T> addProblems( Result<T> result, Iterable<? extends ModelProblem> problems )
166     {
167         Collection<ModelProblem> list = new ArrayList<>();
168         for ( ModelProblem item : problems )
169         {
170             list.add( item );
171         }
172         for ( ModelProblem item : result.getProblems() )
173         {
174             list.add( item );
175         }
176         return new Result<>( result.hasErrors() || hasErrors( problems ), result.get(), list );
177     }
178 
179     public static <T> Result<T> addProblems( Result<T> result, Result<?>... results )
180     {
181         final List<ModelProblem> problemsList = new ArrayList<>();
182 
183         for ( Result<?> result1 : results )
184         {
185             for ( ModelProblem modelProblem : result1.getProblems( ) )
186             {
187                 problemsList.add( modelProblem );
188             }
189         }
190         return addProblems( result, problemsList );
191     }
192 
193     /**
194      * Turns the given results into a single result by combining problems and models into single collection.
195      *
196      * @param results
197      */
198     public static <T> Result<Iterable<T>> newResultSet( Iterable<? extends Result<? extends T>> results )
199     {
200         boolean hasErrors = false;
201         List<T> modelsList = new ArrayList<>();
202         List<ModelProblem> problemsList = new ArrayList<>();
203 
204         for ( Result<? extends T> result : results )
205         {
206             modelsList.add( result.get() );
207 
208             for ( ModelProblem modelProblem : result.getProblems() )
209             {
210                 problemsList.add( modelProblem );
211             }
212 
213             if ( result.hasErrors() )
214             {
215                 hasErrors = true;
216             }
217         }
218         return new Result<>( hasErrors, ( Iterable<T> ) modelsList, problemsList );
219     }
220 
221     // helper to determine if problems contain error
222     private static boolean hasErrors( Iterable<? extends ModelProblem> problems )
223     {
224         for ( ModelProblem input : problems )
225         {
226             if ( input.getSeverity().equals( ERROR ) || input.getSeverity().equals( FATAL ) )
227             {
228                 return true;
229             }
230         }
231         return false;
232     }
233 
234     /**
235      * Class definition
236      */
237 
238     private final boolean errors;
239 
240     private final T value;
241 
242     private final Iterable<? extends ModelProblem> problems;
243 
244     private Result( boolean errors, T model, Iterable<? extends ModelProblem> problems )
245     {
246         this.errors = errors;
247         this.value = model;
248         this.problems = problems;
249     }
250 
251     public Iterable<? extends ModelProblem> getProblems()
252     {
253         return problems;
254     }
255 
256     public T get()
257     {
258         return value;
259     }
260 
261     public boolean hasErrors()
262     {
263         return errors;
264     }
265 }