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     */
017    package net.dpml.cli.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 net.dpml.cli.resource.ResourceConstants;
026    import 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="http://www.dpml.net">Digital Product Meta Library</a>
050     * @version 1.0.0
051     */
052    public 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    }