View Javadoc

1   package org.apache.maven.plugin;
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 org.apache.maven.plugin.descriptor.PluginDescriptor;
23  import org.apache.maven.usability.plugin.Expression;
24  import org.apache.maven.usability.plugin.ExpressionDocumentationException;
25  import org.apache.maven.usability.plugin.ExpressionDocumenter;
26  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
27  import org.codehaus.plexus.configuration.PlexusConfiguration;
28  
29  import java.io.PrintWriter;
30  import java.io.StringWriter;
31  import java.util.Arrays;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Properties;
36  import java.util.StringTokenizer;
37  import java.util.regex.Matcher;
38  import java.util.regex.Pattern;
39  
40  /**
41   * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
42   * @version $Id: PluginConfigurationException.java 495147 2007-01-11 07:47:53Z jvanzyl $
43   */
44  public class PluginConfigurationException
45      extends Exception
46  {
47      private final PluginDescriptor pluginDescriptor;
48  
49      private String originalMessage;
50  
51      private static final List UNMODIFIABLE_EXPRESSIONS = Arrays.asList(
52          new String[]{"localRepository", "reactorProjects", "settings", "project", "session", "plugin", "basedir"} );
53  
54      public PluginConfigurationException( PluginDescriptor pluginDescriptor, String message )
55      {
56          super( "Error configuring: " + pluginDescriptor.getPluginLookupKey() + ". Reason: " + message );
57          this.pluginDescriptor = pluginDescriptor;
58          this.originalMessage = message;
59      }
60  
61      public PluginConfigurationException( PluginDescriptor pluginDescriptor, Throwable cause )
62      {
63          super( "Error configuring: " + pluginDescriptor.getPluginLookupKey() + ".", cause );
64          this.pluginDescriptor = pluginDescriptor;
65      }
66  
67      public PluginConfigurationException( PluginDescriptor pluginDescriptor, String message, Throwable cause )
68      {
69          super( "Error configuring: " + pluginDescriptor.getPluginLookupKey() + ". Reason: " + message, cause );
70          this.pluginDescriptor = pluginDescriptor;
71          this.originalMessage = message;
72      }
73  
74      public PluginDescriptor getPluginDescriptor()
75      {
76          return pluginDescriptor;
77      }
78  
79      public String getOriginalMessage()
80      {
81          return originalMessage;
82      }
83  
84      protected static void addParameterUsageInfo( String expression, StringBuffer messageBuffer )
85      {
86          StringBuffer expressionMessageBuffer = new StringBuffer();
87  
88          Matcher exprMatcher = Pattern.compile( "\\$\\{(.+)\\}" ).matcher( expression );
89  
90          boolean unmodifiableElementsFound = false;
91          boolean activeElementsFound = false;
92  
93          int elementCount = 0;
94  
95          while ( exprMatcher.find() )
96          {
97              elementCount++;
98  
99              activeElementsFound = true;
100 
101             String subExpression = exprMatcher.group( 1 );
102 
103             StringTokenizer expressionParts = new StringTokenizer( subExpression, "." );
104 
105             String firstPart = expressionParts.nextToken();
106 
107             Map expressions = null;
108             try
109             {
110                 expressions = ExpressionDocumenter.load();
111             }
112             catch ( ExpressionDocumentationException e )
113             {
114                 expressionMessageBuffer.append( "\n\nERROR!! Failed to load expression documentation!" );
115 
116                 StringWriter sWriter = new StringWriter();
117                 PrintWriter pWriter = new PrintWriter( sWriter );
118 
119                 e.printStackTrace( pWriter );
120 
121                 expressionMessageBuffer.append( "\n\nException:\n\n" ).append( sWriter.toString() );
122             }
123 
124             if ( expressions != null )
125             {
126                 Expression expr = (Expression) expressions.get( subExpression );
127 
128                 if ( expr != null )
129                 {
130                     if ( !expr.isEditable() )
131                     {
132                         unmodifiableElementsFound = true;
133                     }
134                     else
135                     {
136                         addParameterConfigDocumentation( firstPart, exprMatcher.group( 0 ), subExpression,
137                                                          expressionMessageBuffer, expressions );
138                     }
139                 }
140                 else if ( UNMODIFIABLE_EXPRESSIONS.contains( subExpression ) )
141                 {
142                     unmodifiableElementsFound = true;
143                 }
144                 else
145                 {
146                     expressionMessageBuffer.append( "on the command line, specify: \'-D" ).append( subExpression )
147                         .append( "=VALUE\'" );
148                 }
149             }
150         }
151 
152         if ( activeElementsFound )
153         {
154             messageBuffer.append( expressionMessageBuffer );
155         }
156         else
157         {
158             messageBuffer.append(
159                 "    (found static expression: \'" + expression + "\' which may act as a default value).\n" );
160         }
161 
162         if ( unmodifiableElementsFound )
163         {
164             if ( elementCount > 1 )
165             {
166                 messageBuffer.append( "    " );
167             }
168 
169             messageBuffer
170                 .append( "NOTE: One or more purely derived expression elements were detected in \'" + expression +
171                     "\'.\n    If you continue to get this error after any other expression elements are specified correctly," +
172                     "\n    please report this issue to the Maven development team.\n" );
173         }
174     }
175 
176     private static void addParameterConfigDocumentation( String firstPart, String wholeExpression, String subExpression,
177                                                          StringBuffer expressionMessageBuffer, Map expressionDoco )
178     {
179         Expression expr = (Expression) expressionDoco.get( subExpression );
180 
181         if ( expr != null )
182         {
183             expressionMessageBuffer.append( "check that the following section of " );
184             if ( "project".equals( firstPart ) )
185             {
186                 expressionMessageBuffer.append( "the pom.xml " );
187             }
188             else if ( "settings".equals( firstPart ) )
189             {
190                 expressionMessageBuffer.append( "your ~/.m2/settings.xml file " );
191             }
192 
193             expressionMessageBuffer.append( "is present and correct:\n\n" );
194 
195             String message = expr.getConfiguration();
196 
197             if ( message == null )
198             {
199                 message = expr.getDescription();
200             }
201 
202             expressionMessageBuffer.append( message );
203 
204             Properties cliConfig = expr.getCliOptions();
205 
206             if ( cliConfig != null && !cliConfig.isEmpty() )
207             {
208                 expressionMessageBuffer.append( "\n\n-OR-\n\nUse the following command-line switches:\n" );
209 
210                 prettyPrintCommandLineSwitches( cliConfig, '.', expressionMessageBuffer );
211             }
212         }
213         else
214         {
215             expressionMessageBuffer.append( "ensure that the expression: \'" + wholeExpression + "\' is satisfied" );
216         }
217     }
218 
219     private static void prettyPrintCommandLineSwitches( Properties switches, char filler,
220                                                         StringBuffer expressionMessageBuffer )
221     {
222         int maxKeyLen = 0;
223 
224         for ( Iterator it = switches.entrySet().iterator(); it.hasNext(); )
225         {
226             Map.Entry entry = (Map.Entry) it.next();
227 
228             String key = (String) entry.getKey();
229 
230             int keyLen = key.length();
231             if ( keyLen > maxKeyLen )
232             {
233                 maxKeyLen = keyLen;
234             }
235         }
236 
237         final int minFillerCount = 4;
238 
239         for ( Iterator it = switches.entrySet().iterator(); it.hasNext(); )
240         {
241             Map.Entry entry = (Map.Entry) it.next();
242 
243             String key = (String) entry.getKey();
244 
245             int keyLen = key.length();
246 
247             int fillerCount = maxKeyLen - keyLen + minFillerCount;
248 
249             expressionMessageBuffer.append( '\n' ).append( key ).append( ' ' );
250 
251             for ( int i = 0; i < fillerCount; i++ )
252             {
253                 expressionMessageBuffer.append( filler );
254             }
255 
256             expressionMessageBuffer.append( ' ' ).append( entry.getValue() );
257         }
258 
259         expressionMessageBuffer.append( '\n' );
260     }
261 
262     public String buildConfigurationDiagnosticMessage( ComponentConfigurationException cce )
263     {
264         StringBuffer message = new StringBuffer();
265 
266         PluginDescriptor descriptor = getPluginDescriptor();
267 
268         PlexusConfiguration failedConfiguration = cce.getFailedConfiguration();
269 
270         message.append( "Failed to configure plugin parameters for: " + descriptor.getId() + "\n\n" );
271 
272         if ( failedConfiguration != null )
273         {
274             String value = failedConfiguration.getValue( null );
275             if ( value != null )
276             {
277                 addParameterUsageInfo( value, message );
278             }
279         }
280 
281         message.append( "\n\nCause: " ).append( cce.getMessage() );
282 
283         return message.toString();
284     }
285 }