001    package org.apache.maven.model.building;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.io.PrintWriter;
023    import java.io.StringWriter;
024    import java.util.Collections;
025    import java.util.List;
026    
027    import org.apache.maven.model.Model;
028    
029    /**
030     * Signals one ore more errors during model building. The model builder tries to collect as many problems as possible
031     * before eventually failing to provide callers with rich error information. Use {@link #getProblems()} to query the
032     * details of the failure.
033     * 
034     * @author Benjamin Bentmann
035     */
036    public class ModelBuildingException
037        extends Exception
038    {
039    
040        private final ModelBuildingResult result;
041    
042        /**
043         * Creates a new exception with the specified problems.
044         * 
045         * @param model The model that could not be built, may be {@code null}.
046         * @param modelId The identifier of the model that could not be built, may be {@code null}.
047         * @param problems The problems that causes this exception, may be {@code null}.
048         * @deprecated Use {@link #ModelBuildingException(ModelBuildingResult)} instead.
049         */
050        @Deprecated
051        public ModelBuildingException( Model model, String modelId, List<ModelProblem> problems )
052        {
053            super( toMessage( modelId, problems ) );
054    
055            if ( model != null )
056            {
057                DefaultModelBuildingResult tmp = new DefaultModelBuildingResult();
058                if ( modelId == null )
059                {
060                    modelId = "";
061                }
062                tmp.addModelId( modelId );
063                tmp.setRawModel( modelId, model );
064                tmp.setProblems( problems );
065                result = tmp;
066            }
067            else
068            {
069                result = null;
070            }
071        }
072    
073        /**
074         * Creates a new exception from the specified interim result and its associated problems.
075         * 
076         * @param result The interim result, may be {@code null}.
077         */
078        public ModelBuildingException( ModelBuildingResult result )
079        {
080            super( toMessage( result ) );
081            this.result = result;
082        }
083    
084        /**
085         * Gets the interim result of the model building up to the point where it failed.
086         * 
087         * @return The interim model building result or {@code null} if not available.
088         */
089        public ModelBuildingResult getResult()
090        {
091            return result;
092        }
093    
094        /**
095         * Gets the model that could not be built properly.
096         * 
097         * @return The erroneous model or {@code null} if not available.
098         */
099        public Model getModel()
100        {
101            if ( result == null )
102            {
103                return null;
104            }
105            if ( result.getEffectiveModel() != null )
106            {
107                return result.getEffectiveModel();
108            }
109            return result.getRawModel();
110        }
111    
112        /**
113         * Gets the identifier of the POM whose effective model could not be built. The general format of the identifier is
114         * {@code <groupId>:<artifactId>:<version>} but some of these coordinates may still be unknown at the point the
115         * exception is thrown so this information is merely meant to assist the user.
116         * 
117         * @return The identifier of the POM or an empty string if not known, never {@code null}.
118         */
119        public String getModelId()
120        {
121            if ( result == null || result.getModelIds().isEmpty() )
122            {
123                return "";
124            }
125            return result.getModelIds().get( 0 );
126        }
127    
128        /**
129         * Gets the problems that caused this exception.
130         * 
131         * @return The problems that caused this exception, never {@code null}.
132         */
133        public List<ModelProblem> getProblems()
134        {
135            if ( result == null )
136            {
137                return Collections.emptyList();
138            }
139            return result.getProblems();
140        }
141    
142        private static String toMessage( ModelBuildingResult result )
143        {
144            if ( result != null && !result.getModelIds().isEmpty() )
145            {
146                return toMessage( result.getModelIds().get( 0 ), result.getProblems() );
147            }
148            return null;
149        }
150    
151        private static String toMessage( String modelId, List<ModelProblem> problems )
152        {
153            StringWriter buffer = new StringWriter( 1024 );
154    
155            PrintWriter writer = new PrintWriter( buffer );
156    
157            writer.print( problems.size() );
158            writer.print( ( problems.size() == 1 ) ? " problem was " : " problems were " );
159            writer.print( "encountered while building the effective model" );
160            if ( modelId != null && modelId.length() > 0 )
161            {
162                writer.print( " for " );
163                writer.print( modelId );
164            }
165            writer.println();
166    
167            for ( ModelProblem problem : problems )
168            {
169                writer.print( "[" );
170                writer.print( problem.getSeverity() );
171                writer.print( "] " );
172                writer.print( problem.getMessage() );
173                writer.print( " @ " );
174                writer.println( ModelProblemUtils.formatLocation( problem, modelId ) );
175            }
176    
177            return buffer.toString();
178        }
179    
180    }