View Javadoc
1   /*
2    * Copyright 2001-2008 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  
18  package org.apache.juddi.validation;
19  
20  import java.util.List;
21  import java.util.StringTokenizer;
22  
23  import org.apache.juddi.keygen.KeyGenerator;
24  import org.apache.juddi.v3.error.ErrorMessage;
25  import org.apache.juddi.v3.error.InvalidKeyPassedException;
26  import org.apache.juddi.v3.error.ValueNotAllowedException;
27  import org.uddi.v3_service.DispositionReportFaultMessage;
28  
29  /**
30   * @author <a href="mailto:jfaath@apache.org">Jeff Faath</a>
31   * @author <a href="mailto:tcunning@apache.org">Tom Cunningham</a>
32   */
33  public class ValidateUDDIKey {
34  
35  	public static void validateUDDIv3Key(String key) throws DispositionReportFaultMessage {
36  		if (key == null)
37  			throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.NullKey"));
38  		if (key.toLowerCase().startsWith("uuid:")) {
39                          return;
40                  }
41  		if (! key.contains(KeyGenerator.PARTITION_SEPARATOR)) return; //v2 style key; no other validation rules apply
42  		
43  		String keyToTest = key.trim();
44  		if (keyToTest.endsWith(KeyGenerator.PARTITION_SEPARATOR))
45  			throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.MalformedKey", key));
46  
47  		StringTokenizer tokenizer = new StringTokenizer(key.toLowerCase(), KeyGenerator.PARTITION_SEPARATOR);
48  		
49  		for(int count = 0; tokenizer.hasMoreTokens(); count++) {
50  			String nextToken = tokenizer.nextToken();
51  
52  			if (count == 0) {
53  				if (!ValidateUDDIKey.isValidUDDIScheme(nextToken))
54  					throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.MalformedKey", key));
55  			}
56  			else if (count == 1) {
57  				if(!ValidateUDDIKey.isValidDomainKey(nextToken))
58  					throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.MalformedKey", key));
59  			}
60  			else {
61  				if (!isValidKSS(nextToken))
62  					throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.MalformedKey", key));
63  			}
64  		}
65  	}
66  	
67  	public static void validateUDDIv3KeyGeneratorKey(String key) throws DispositionReportFaultMessage {
68  		if (key == null)
69  			throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.NullKeys"));
70  		
71  		if ( !(key.toUpperCase().endsWith(KeyGenerator.KEYGENERATOR_SUFFIX.toUpperCase())) )
72  			throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.KeyGenSuffix", key));
73  		
74  		validateUDDIv3Key(key.substring(0, key.lastIndexOf(KeyGenerator.PARTITION_SEPARATOR)));
75  	}
76  	
77  	public static void validateUDDIv3KeyGeneratorTModel(org.uddi.api_v3.TModel tModel) throws DispositionReportFaultMessage {
78  		if (tModel == null)
79  			throw new ValueNotAllowedException(new ErrorMessage("errors.tmodel.NullInput"));
80  		
81  		validateUDDIv3KeyGeneratorKey(tModel.getTModelKey());
82  
83  		// A key generator key should have exactly one category and it's key value should be 'keyGenerator'
84  		org.uddi.api_v3.CategoryBag categories = tModel.getCategoryBag();
85  		if (categories != null) {
86  			List<org.uddi.api_v3.KeyedReference> elems = categories.getKeyedReference();
87  			if (elems != null && elems.size() == 1) {
88  				org.uddi.api_v3.KeyedReference elem = elems.get(0);
89  				if (elem != null) {
90  					if (elem instanceof org.uddi.api_v3.KeyedReference) {
91  						String keyedValue = elem.getKeyValue();
92  						if (keyedValue != null) {
93  							if (keyedValue.equalsIgnoreCase(KeyGenerator.KEYGENERATOR_SUFFIX))
94  								return;
95  						}
96  					}
97  				}
98  			}
99  		}
100 
101 		throw new ValueNotAllowedException(new ErrorMessage("errors.tmodel.keygenerator.BadCategory"));
102 	}
103 	
104 	public static boolean isValidUDDIScheme(String token) {
105 		if (token == null)
106 			return false;
107 		
108 		if (!KeyGenerator.UDDI_SCHEME.equalsIgnoreCase(token))
109 			return false;
110 
111 		return true;
112 
113 	}
114 	
115 	public static boolean isValidDomainKey(String token) {
116 		if(token.indexOf("..") != -1)
117 			return false;
118 
119 		StringTokenizer tokenizer = new StringTokenizer(token, ".");
120 		int tokensCount = tokenizer.countTokens();
121 		for(int i = 0; tokenizer.hasMoreTokens(); i++) {
122 			String domainPart = tokenizer.nextToken();
123 			if(i == tokensCount - 1) {
124 				if(!isValidTopLabel(domainPart)) {
125 					return false;
126 				}
127 			} else if(!isValidDomainLabel(domainPart)) {
128 				return false;
129 			}
130 		}
131 		return true;
132 	}
133 	
134 
135 	private static boolean isValidDomainLabel(String token) {
136 		char[] chars = token.toCharArray();
137 		for(int i = 0; i < chars.length; i++) {
138 			char c = chars[i];
139 			if(c != '-' && !Character.isLetterOrDigit(c)) {
140 				return false;
141 			}
142 		}
143 		return true;
144 	}
145 
146 	private static boolean isValidTopLabel(String token) {
147 		return Character.isLetter(token.charAt(0)) && (token.length() == 1 || isValidDomainLabel(token.substring(1)));
148 	}
149 	
150 	public static boolean isValidKSS(String token) {
151 		if (token.length() == 0)
152 			return false;
153 
154 		// The key generator suffix is a reserved word and cannot be found in any part of the KSS 
155 		if (token.equalsIgnoreCase(KeyGenerator.KEYGENERATOR_SUFFIX))
156 			return false;
157 
158 		return true;
159 	}
160 }