001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.cli2.validation;
018
019import java.net.MalformedURLException;
020import java.net.URL;
021
022import java.util.List;
023import java.util.ListIterator;
024
025import org.apache.commons.cli2.resource.ResourceConstants;
026import org.apache.commons.cli2.resource.ResourceHelper;
027
028/**
029 * The <code>UrlValidator</code> validates the string argument
030 * values are URLs.  If the value is a URL, the string value in
031 * the {@link java.util.List} of values is replaced with the
032 * {@link java.net.URL} instance.
033 *
034 * URLs can also be validated based on their scheme by using
035 * the {@link #setProtocol setProtocol} method, or by using the specified
036 * {@link #UrlValidator(java.lang.String) constructor}.
037 *
038 * The following example shows how to limit the valid values
039 * for the site argument to 'https' URLs.
040 *
041 * <pre>
042 * ...
043 * ArgumentBuilder builder = new ArgumentBuilder();
044 * Argument site =
045 *     builder.withName("site");
046 *            .withValidator(new URLValidator("https"));
047 * </pre>
048 *
049 * @author Rob Oxspring
050 * @author John Keyes
051 */
052public class UrlValidator implements Validator {
053    /** allowed protocol */
054    private String protocol = null;
055
056    /**
057     * Creates a UrlValidator.
058     */
059    public UrlValidator() {
060    }
061
062    /**
063     * Creates a UrlValidator for the specified protocol.
064     * @param protocol the protocol to be used
065     */
066    public UrlValidator(final String protocol) {
067        setProtocol(protocol);
068    }
069
070    /**
071     * Validate the list of values against the list of permitted values.
072     * If a value is valid, replace the string in the <code>values</code>
073     * {@link java.util.List} with the { java.net.URL} instance.
074     *
075     * @see org.apache.commons.cli2.validation.Validator#validate(java.util.List)
076     */
077    public void validate(final List values)
078        throws InvalidArgumentException {
079        for (final ListIterator i = values.listIterator(); i.hasNext();) {
080            final String name = (String) i.next();
081
082            try {
083                final URL url = new URL(name);
084
085                if ((protocol != null) && !protocol.equals(url.getProtocol())) {
086                    throw new InvalidArgumentException(name);
087                }
088
089                i.set(url);
090            } catch (final MalformedURLException mue) {
091                throw new InvalidArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.URLVALIDATOR_MALFORMED_URL,
092                                                                                                 new Object[] {
093                                                                                                     name
094                                                                                                 }));
095            }
096        }
097    }
098
099    /**
100     * Returns the protocol that must be used by a valid URL.
101     *
102     * @return the protocol that must be used by a valid URL.
103     */
104    public String getProtocol() {
105        return protocol;
106    }
107
108    /**
109     * Specifies the protocol that a URL must have to be valid.
110     *
111     * @param protocol the protocol that a URL must have to be valid.
112     */
113    public void setProtocol(String protocol) {
114        this.protocol = protocol;
115    }
116}