001/*
002 * Copyright 2003-2005 The Apache Software Foundation
003 * Copyright 2005 Stephen McConnell
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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 net.dpml.cli.validation;
018
019import java.net.MalformedURLException;
020import java.net.URL;
021
022import java.util.List;
023import java.util.ListIterator;
024
025import net.dpml.cli.resource.ResourceConstants;
026import net.dpml.cli.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 <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
050 * @version @PROJECT-VERSION@
051 */
052public class URLValidator implements Validator 
053{
054    /** allowed protocol */
055    private String m_protocol = null;
056
057    /**
058     * Creates a URLValidator.
059     */
060    public URLValidator() 
061    {
062    }
063
064    /**
065     * Creates a URLValidator for the specified protocol.
066     * @param protocol the url protocol
067     */
068    public URLValidator( final String protocol ) 
069    {
070        setProtocol( protocol );
071    }
072
073   /**
074    * Validate the list of values against the list of permitted values.
075    * If a value is valid, replace the string in the <code>values</code>
076    * {@link java.util.List} with the { java.net.URL} instance.
077    *
078    * @param values the list of values to validate 
079    * @exception InvalidArgumentException if a value is invalid
080    * @see net.dpml.cli.validation.Validator#validate(java.util.List)
081    */
082    public void validate( final List values ) throws InvalidArgumentException
083    {
084        for( final ListIterator i = values.listIterator(); i.hasNext();) 
085        {
086            final Object next = i.next();
087            if( next instanceof URL )
088            {
089                return;
090            }
091            final String name = (String) next;
092            try
093            {
094                final URL url = new URL( name );
095                if( ( m_protocol != null ) && !m_protocol.equals( url.getProtocol() ) ) 
096                {
097                    throw new InvalidArgumentException( name );
098                }
099                i.set( url );
100            }
101            catch( final MalformedURLException mue ) 
102            {
103                throw new InvalidArgumentException(
104                  ResourceHelper.getResourceHelper().getMessage(
105                    ResourceConstants.URLVALIDATOR_MALFORMED_URL,
106                    new Object[]{name} ) );
107            }
108        }
109    }
110
111    /**
112     * Returns the protocol that must be used by a valid URL.
113     *
114     * @return the protocol that must be used by a valid URL.
115     */
116    public String getProtocol()
117    {
118        return m_protocol;
119    }
120
121    /**
122     * Specifies the protocol that a URL must have to be valid.
123     *
124     * @param protocol the protocol that a URL must have to be valid.
125     */
126    public void setProtocol( String protocol )
127    {
128        m_protocol = protocol;
129    }
130}