001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.scm;
020
021import java.io.File;
022import java.io.Serializable;
023import java.util.Date;
024import java.util.HashMap;
025import java.util.Map;
026
027/**
028 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
029 * @author Olivier Lamy
030 */
031public class CommandParameters implements Serializable {
032    private static final long serialVersionUID = -7346070735958137283L;
033
034    private Map<String, Object> parameters = new HashMap<>();
035
036    // ----------------------------------------------------------------------
037    // String
038    // ----------------------------------------------------------------------
039
040    /**
041     * Return the parameter value as String.
042     *
043     * @param parameter the parameter
044     * @return the parameter value as a String
045     * @throws ScmException if the parameter doesn't exist
046     */
047    public String getString(CommandParameter parameter) throws ScmException {
048        Object object = getObject(String.class, parameter);
049
050        return object.toString();
051    }
052
053    /**
054     * Return the parameter value or the default value if it doesn't exist.
055     *
056     * @param parameter    the parameter
057     * @param defaultValue the default value
058     * @return the parameter value as a String
059     * @throws ScmException if the value is in the wrong type
060     */
061    public String getString(CommandParameter parameter, String defaultValue) throws ScmException {
062        Object object = getObject(String.class, parameter, null);
063
064        if (object == null) {
065            return defaultValue;
066        }
067
068        return object.toString();
069    }
070
071    /**
072     * Set a parameter value.
073     *
074     * @param parameter the parameter name
075     * @param value     the value of the parameter
076     * @throws ScmException if the parameter already exist
077     */
078    public void setString(CommandParameter parameter, String value) throws ScmException {
079        setObject(parameter, value);
080    }
081
082    // ----------------------------------------------------------------------
083    // Int
084    // ----------------------------------------------------------------------
085
086    /**
087     * Return the parameter value as int.
088     *
089     * @param parameter the parameter
090     * @return the parameter value as a String
091     * @throws ScmException if the parameter doesn't exist
092     */
093    public int getInt(CommandParameter parameter) throws ScmException {
094        return ((Integer) getObject(Integer.class, parameter)).intValue();
095    }
096
097    /**
098     * Return the parameter value as int or the default value if it doesn't exist.
099     *
100     * @param parameter    the parameter
101     * @param defaultValue the default value
102     * @return the parameter value as an int
103     * @throws ScmException if the value is in the wrong type
104     */
105    public int getInt(CommandParameter parameter, int defaultValue) throws ScmException {
106        Integer value = ((Integer) getObject(Integer.class, parameter, null));
107
108        if (value == null) {
109            return defaultValue;
110        }
111
112        return value.intValue();
113    }
114
115    /**
116     * Set a parameter value.
117     *
118     * @param parameter the parameter name
119     * @param value     the value of the parameter
120     * @throws ScmException if the parameter already exist
121     */
122    public void setInt(CommandParameter parameter, int value) throws ScmException {
123        setObject(parameter, Integer.valueOf(value));
124    }
125
126    // ----------------------------------------------------------------------
127    // Date
128    // ----------------------------------------------------------------------
129
130    /**
131     * Return the parameter value as Date.
132     *
133     * @param parameter the parameter
134     * @return the parameter value as a Date
135     * @throws ScmException if the parameter doesn't exist
136     */
137    public Date getDate(CommandParameter parameter) throws ScmException {
138        return (Date) getObject(Date.class, parameter);
139    }
140
141    /**
142     * Return the parameter value as String or the default value if it doesn't exist.
143     *
144     * @param parameter    the parameter
145     * @param defaultValue the defaultValue
146     * @return the parameter value as a Date
147     * @throws ScmException if the value is in the wrong type
148     */
149    public Date getDate(CommandParameter parameter, Date defaultValue) throws ScmException {
150        return (Date) getObject(Date.class, parameter, defaultValue);
151    }
152
153    /**
154     * Set a parameter value.
155     *
156     * @param parameter the parameter name
157     * @param date      the value of the parameter
158     * @throws ScmException if the parameter already exist
159     */
160    public void setDate(CommandParameter parameter, Date date) throws ScmException {
161        setObject(parameter, date);
162    }
163
164    // ----------------------------------------------------------------------
165    // Boolean
166    // ----------------------------------------------------------------------
167
168    /**
169     * Return the parameter value as boolean.
170     *
171     * @param parameter the parameter
172     * @return the parameter value as a boolean
173     * @throws ScmException if the parameter doesn't exist
174     */
175    public boolean getBoolean(CommandParameter parameter) throws ScmException {
176        return Boolean.valueOf(getString(parameter)).booleanValue();
177    }
178
179    /**
180     * Return the parameter value as boolean.
181     *
182     * @param parameter    the parameter
183     * @param defaultValue default value if parameter not exists
184     * @return the parameter value as a boolean
185     * @throws ScmException if the parameter doesn't exist
186     * @since 1.7
187     */
188    public boolean getBoolean(CommandParameter parameter, boolean defaultValue) throws ScmException {
189        return Boolean.parseBoolean(getString(parameter, Boolean.toString(defaultValue)));
190    }
191
192    // ----------------------------------------------------------------------
193    // ScmVersion
194    // ----------------------------------------------------------------------
195
196    /**
197     * Return the parameter value as ScmVersion.
198     *
199     * @param parameter the parameter
200     * @return the parameter value as a ScmVersion
201     * @throws ScmException if the parameter doesn't exist
202     */
203    public ScmVersion getScmVersion(CommandParameter parameter) throws ScmException {
204        return (ScmVersion) getObject(ScmVersion.class, parameter);
205    }
206
207    /**
208     * Return the parameter value as ScmVersion or the default value.
209     *
210     * @param parameter    the parameter
211     * @param defaultValue the default value
212     * @return the parameter value as a ScmVersion
213     * @throws ScmException if the parameter doesn't exist
214     */
215    public ScmVersion getScmVersion(CommandParameter parameter, ScmVersion defaultValue) throws ScmException {
216        return (ScmVersion) getObject(ScmVersion.class, parameter, defaultValue);
217    }
218
219    /**
220     * Set a parameter value.
221     *
222     * @param parameter  the parameter name
223     * @param scmVersion the tbranch/tag/revision
224     * @throws ScmException if the parameter already exist
225     */
226    public void setScmVersion(CommandParameter parameter, ScmVersion scmVersion) throws ScmException {
227        setObject(parameter, scmVersion);
228    }
229
230    // ----------------------------------------------------------------------
231    // File[]
232    // ----------------------------------------------------------------------
233
234    /**
235     * @param parameter not null
236     * @return an array of files
237     * @throws ScmException if any
238     */
239    public File[] getFileArray(CommandParameter parameter) throws ScmException {
240        return (File[]) getObject(File[].class, parameter);
241    }
242
243    /**
244     * @param parameter    not null
245     * @param defaultValue could be null
246     * @return an array of files
247     * @throws ScmException if any
248     */
249    public File[] getFileArray(CommandParameter parameter, File[] defaultValue) throws ScmException {
250        return (File[]) getObject(File[].class, parameter, defaultValue);
251    }
252
253    public ScmTagParameters getScmTagParameters(CommandParameter parameter) throws ScmException {
254        return (ScmTagParameters) getObject(ScmTagParameters.class, parameter, new ScmTagParameters());
255    }
256
257    public void setScmTagParameters(CommandParameter parameter, ScmTagParameters scmTagParameters) throws ScmException {
258        setObject(parameter, scmTagParameters);
259    }
260
261    public void setScmBranchParameters(CommandParameter parameter, ScmBranchParameters scmBranchParameters)
262            throws ScmException {
263        setObject(parameter, scmBranchParameters);
264    }
265
266    public ScmBranchParameters getScmBranchParameters(CommandParameter parameter) throws ScmException {
267        return (ScmBranchParameters) getObject(ScmBranchParameters.class, parameter, new ScmBranchParameters());
268    }
269
270    // ----------------------------------------------------------------------
271    // SigningOption (Git specific)
272    // ----------------------------------------------------------------------
273    /**
274     * The sign option for a commit or tag.
275     * <p>
276     * This is only relevant for SCM providers that support signing commits/tags, such as Git.
277     * </p>
278     *
279     * @see <a href="https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work">Git Tools - Signing Your Work</a>
280     */
281    public enum SignOption {
282        /**
283         * Signs the commit/tag irrespective of the Git configuration setting {@code commit.gpgSign} or {@code tag.gpgSign}.
284         * Only has an effect for supported SCM providers. Others may be silently ignoring this setting.
285         */
286        FORCE_SIGN,
287        /**
288         * Just uses the default value in the Git configuration for setting {@code commit.gpgSign} or {@code tag.gpgSign}.
289         * Only has an effect for supported SCM providers. Others may be silently ignoring this setting.
290         */
291        DEFAULT,
292        /**
293         * Does not sign the commit/tag irrespective of the Git configuration setting {@code commit.gpgSign} or {@code tag.gpgSign}.
294         */
295        FORCE_NO_SIGN
296    }
297
298    public void setSignOption(CommandParameter parameter, SignOption signOption) throws ScmException {
299        setObject(parameter, signOption);
300    }
301
302    /**
303     * Return the sign option.
304     *
305     * @param parameter the parameter
306     * @return the sign option or null if not set
307     * @throws ScmException if the parameter has the wrong type
308     */
309    public SignOption getSignOption(CommandParameter parameter) throws ScmException {
310        return getObject(SignOption.class, parameter, null);
311    }
312
313    // ----------------------------------------------------------------------
314    //
315    // ----------------------------------------------------------------------
316
317    /**
318     * Return the value object.
319     *
320     * @param clazz     the type of the parameter value
321     * @param parameter the parameter
322     * @return the parameter value
323     * @throws ScmException if the parameter doesn't exist
324     */
325    private <T> T getObject(Class<T> clazz, CommandParameter parameter) throws ScmException {
326        T object = getObject(clazz, parameter, null);
327
328        if (object == null) {
329            throw new ScmException("Missing parameter: '" + parameter.getName() + "'.");
330        }
331
332        return object;
333    }
334
335    /**
336     * Return the value object or the default value if it doesn't exist.
337     *
338     * @param clazz        the type of the parameter value
339     * @param parameter    the parameter
340     * @param defaultValue the defaultValue
341     * @return the parameter value
342     * @throws ScmException if the defaultValue is in the wrong type
343     */
344    @SuppressWarnings("unchecked")
345    private <T> T getObject(Class<T> clazz, CommandParameter parameter, T defaultValue) throws ScmException {
346        Object object = parameters.get(parameter.getName());
347
348        if (object == null) {
349            return defaultValue;
350        }
351
352        if (clazz != null && !clazz.isAssignableFrom(object.getClass())) {
353            throw new ScmException("Wrong parameter type for '" + parameter.getName() + ". " + "Expected: "
354                    + clazz.getName() + ", got: " + object.getClass().getName());
355        }
356
357        return (T) object;
358    }
359
360    /**
361     * Set the parameter value.
362     *
363     * @param parameter the parameter
364     * @param value     the parameter value
365     * @throws ScmException if the parameter already exist
366     */
367    private void setObject(CommandParameter parameter, Object value) throws ScmException {
368        Object object = getObject(null, parameter, null);
369
370        if (object != null) {
371            throw new ScmException("The parameter is already set: " + parameter.getName());
372        }
373
374        parameters.put(parameter.getName(), value);
375    }
376
377    /**
378     * Removes a parameter, silent if it didn't exist.
379     *
380     * @param parameter to remove
381     */
382    public void remove(CommandParameter parameter) {
383        parameters.remove(parameter.getName());
384    }
385}