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     */
017    package org.apache.commons.cli2.validation;
018    
019    import java.net.MalformedURLException;
020    import java.net.URL;
021    
022    import java.util.List;
023    import java.util.ListIterator;
024    
025    import org.apache.commons.cli2.resource.ResourceConstants;
026    import 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     */
052    public 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    }