001 /*
002 * Copyright 2005 Stephen J. McConnell
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package net.dpml.cli.validation;
017
018 import java.net.URISyntaxException;
019 import java.net.URI;
020
021 import java.util.List;
022 import java.util.ListIterator;
023
024 /**
025 * The <code>URIValidator</code> validates the string argument
026 * values are valid URIs. If the value is a URI, the string value in
027 * the {@link java.util.List} of values is replaced with the
028 * {@link java.net.URI} instance.
029 *
030 * The following example shows how to limit the valid values
031 * for the site argument to 'artifact' URIs.
032 *
033 * <pre>
034 * ...
035 * ArgumentBuilder builder = new ArgumentBuilder();
036 * Argument plugin =
037 * builder
038 * .withName("plugin");
039 * .withValidator( new URIValidator( "artifact", "link" ) );
040 * </pre>
041 *
042 * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
043 * @version @PROJECT-VERSION@
044 */
045 public class URIValidator implements Validator
046 {
047 private final String[] m_schemes;
048
049 /**
050 * Creates a UriValidator.
051 */
052 public URIValidator()
053 {
054 m_schemes = new String[0];
055 }
056
057 /**
058 * Creates a UriValidator for the specified scheme.
059 * @param scheme the uri scheme
060 */
061 public URIValidator( final String scheme )
062 {
063 m_schemes = new String[]{scheme};
064 }
065
066 /**
067 * Creates a UriValidator for the specified schemes.
068 * @param schemes an array of schemes
069 */
070 public URIValidator( final String[] schemes )
071 {
072 m_schemes = schemes;
073 }
074
075 /**
076 * Validate the list of values against the list of permitted values.
077 * If a value is valid, replace the string in the <code>values</code>
078 * {@link java.util.List} with the {@link java.net.URI} instance.
079 *
080 * @param values the list of values to validate
081 * @exception InvalidArgumentException if a value is invalid
082 * @see net.dpml.cli.validation.Validator#validate(java.util.List)
083 */
084 public void validate( final List values )
085 throws InvalidArgumentException
086 {
087 for( final ListIterator i = values.listIterator(); i.hasNext();)
088 {
089 final Object object = i.next();
090 if( object instanceof URI )
091 {
092 break;
093 }
094 final String name = (String) object;
095 try
096 {
097 final URI uri = new URI( name );
098 if( m_schemes.length == 0 )
099 {
100 i.set( uri );
101 }
102 else
103 {
104 if( match( uri ) )
105 {
106 i.set( uri );
107 }
108 else
109 {
110 throw new InvalidArgumentException( name );
111 }
112 }
113 }
114 catch( final URISyntaxException e )
115 {
116 final String error =
117 "Bad uri syntax in value [" + name + "].";
118 throw new InvalidArgumentException( error );
119 }
120 }
121 }
122
123 private boolean match( URI uri )
124 {
125 String scheme = uri.getScheme();
126 for( int i=0; i<m_schemes.length; i++ )
127 {
128 if( scheme.startsWith( m_schemes[i] ) )
129 {
130 return true;
131 }
132 }
133 return false;
134 }
135 }