001package org.apache.maven.plugin;
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
022import java.util.Collection;
023import java.util.Iterator;
024import java.util.List;
025import java.util.Map;
026import java.util.Properties;
027
028import org.apache.maven.plugin.descriptor.MojoDescriptor;
029import org.apache.maven.plugin.descriptor.Parameter;
030import org.codehaus.plexus.util.StringUtils;
031
032public class PluginParameterException
033    extends PluginConfigurationException
034{
035
036    private final List<Parameter> parameters;
037
038    private final MojoDescriptor mojo;
039
040    public PluginParameterException( MojoDescriptor mojo, List<Parameter> parameters )
041    {
042        super( mojo.getPluginDescriptor(), "The parameters " + format( parameters ) + " for goal "
043            + mojo.getRoleHint() + " are missing or invalid" );
044
045        this.mojo = mojo;
046
047        this.parameters = parameters;
048    }
049
050    private static String format( List<Parameter> parameters )
051    {
052        StringBuilder buffer = new StringBuilder( 128 );
053        if ( parameters != null )
054        {
055            for ( Parameter parameter : parameters )
056            {
057                if ( buffer.length() > 0 )
058                {
059                    buffer.append( ", " );
060                }
061                buffer.append( '\'' ).append( parameter.getName() ).append( '\'' );
062            }
063        }
064        return buffer.toString();
065    }
066
067    public MojoDescriptor getMojoDescriptor()
068    {
069        return mojo;
070    }
071
072    public List<Parameter> getParameters()
073    {
074        return parameters;
075    }
076
077    private static void decomposeParameterIntoUserInstructions( MojoDescriptor mojo, Parameter param,
078                                                                StringBuilder messageBuffer )
079    {
080        String expression = param.getExpression();
081        
082        if ( param.isEditable() )
083        {
084            boolean isArray = param.getType().endsWith( "[]" );
085            boolean isCollection = false;
086            boolean isMap = false;
087            boolean isProperties = false;
088            if ( !isArray )
089            {
090                try
091                {
092                    //assuming Type is available in current ClassLoader
093                    isCollection = Collection.class.isAssignableFrom( Class.forName( param.getType() ) );
094                    isMap = Map.class.isAssignableFrom( Class.forName( param.getType() ) );
095                    isProperties = Properties.class.isAssignableFrom( Class.forName( param.getType() ) );
096                }
097                catch ( ClassNotFoundException e )
098                {
099                    // assume it is not assignable from Collection or Map
100                }
101            }
102            
103            messageBuffer.append( "Inside the definition for plugin \'" );
104            messageBuffer.append( mojo.getPluginDescriptor().getArtifactId() );
105            messageBuffer.append( "\', specify the following:\n\n<configuration>\n  ...\n" );
106            messageBuffer.append( "  <" ).append( param.getName() ).append( '>' );
107            if ( isArray || isCollection )
108            {
109                messageBuffer.append( '\n' );
110                messageBuffer.append( "    <item>" );
111            }
112            else if ( isProperties )
113            {
114                messageBuffer.append( '\n' );
115                messageBuffer.append( "    <property>\n" );
116                messageBuffer.append( "      <name>KEY</name>\n" );
117                messageBuffer.append( "      <value>" );
118            }
119            else if ( isMap )
120            {
121                messageBuffer.append( '\n' );
122                messageBuffer.append( "    <KEY>" );
123            }
124            messageBuffer.append( "VALUE" );
125            if ( isArray || isCollection )
126            {
127                messageBuffer.append( "</item>\n" );
128                messageBuffer.append( "  " );
129            }
130            else if ( isProperties )
131            {
132                messageBuffer.append( "</value>\n" );
133                messageBuffer.append( "    </property>\n" );
134                messageBuffer.append( "  " );
135            }
136            else if ( isMap )
137            {
138                messageBuffer.append( "</KEY>\n" );
139                messageBuffer.append( "  " );
140            }    
141            messageBuffer.append( "</" ).append( param.getName() ).append( ">\n" );
142            messageBuffer.append( "</configuration>" );
143
144            String alias = param.getAlias();
145            if ( StringUtils.isNotEmpty( alias ) && !alias.equals( param.getName() ) )
146            {
147                messageBuffer.append(
148                    "\n\n-OR-\n\n<configuration>\n  ...\n  <" + alias + ">VALUE</" + alias + ">\n</configuration>\n" );
149            }
150        }
151
152        if ( StringUtils.isEmpty( expression ) )
153        {
154            messageBuffer.append( "." );
155        }
156        else
157        {
158            if ( param.isEditable() )
159            {
160                messageBuffer.append( "\n\n-OR-\n\n" );
161            }
162
163            //addParameterUsageInfo( expression, messageBuffer );
164        }
165    }
166
167    public String buildDiagnosticMessage()
168    {
169        StringBuilder messageBuffer = new StringBuilder( 256 );
170
171        List<Parameter> params = getParameters();
172        MojoDescriptor mojo = getMojoDescriptor();
173
174        messageBuffer.append( "One or more required plugin parameters are invalid/missing for \'" )
175            .append( mojo.getPluginDescriptor().getGoalPrefix() ).append( ":" ).append( mojo.getGoal() )
176            .append( "\'\n" );
177
178        int idx = 0;
179        for ( Iterator<Parameter> it = params.iterator(); it.hasNext(); idx++ )
180        {
181            Parameter param = it.next();
182
183            messageBuffer.append( "\n[" ).append( idx ).append( "] " );
184
185            decomposeParameterIntoUserInstructions( mojo, param, messageBuffer );
186
187            messageBuffer.append( "\n" );
188        }
189
190        return messageBuffer.toString();
191    }
192}