1 package org.apache.maven.plugin;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
42
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 }