1   package com.trendmicro.grid.acl.ds.jpa.util;
2   
3   import static net.sf.tinyjee.util.Assert.assertNotEmpty;
4   
5   import javax.xml.bind.ValidationException;
6   import javax.naming.InvalidNameException;
7   import java.util.StringTokenizer;
8   
9   /**
10   * Validates vendor, packageFamily and package names for plausibility.
11   *
12   * @author Juergen_Kellerer, 2010-06-11
13   * @version 1.0
14   */
15  public class NameValidator {
16  
17  	public static final class InvalidNameException extends IllegalArgumentException {
18  
19  		private static final long serialVersionUID = 9176316552965082594L;
20  
21  		public InvalidNameException(String s) {
22  			super(s);
23  		}
24  	}
25  
26  	private static final NameValidator instance = new NameValidator();
27  
28  	public static NameValidator getInstance() {
29  		return instance;
30  	}
31  
32  	void assertNameContainsValidChars(String nameType, String name, String nameToCheck) {
33  		if (nameToCheck == null || nameToCheck.isEmpty()) {
34  			throw new IllegalArgumentException("The " + nameType +
35  					" element is empty inside the name '" + name + "'.");
36  		}
37  
38  		boolean ws = false, leading = true;
39  		for (char c : nameToCheck.toCharArray()) {
40  			ws = Character.isWhitespace(c);
41  			if (!ws)
42  				leading = false;
43  			if (ws && leading)
44  				throw new InvalidNameException("Found leading whitespaces in " + nameType + " '" + name + "'.");
45  			if (Character.isUpperCase(c))
46  				throw new InvalidNameException("Found upper case character '" + c + "' in " + nameType + " '" + name + "'.");
47  			if (c == ':')
48  				throw new InvalidNameException("Found illegal character ':' in " + nameType + " '" + name + "'.");
49  		}
50  
51  		if (ws)
52  			throw new InvalidNameException("Found trailing whitespaces in " + nameType + " '" + name + "'.");
53  	}
54  
55  	void assertNoMoreTokens(StringTokenizer tokenizer, String name) {
56  		if (tokenizer.hasMoreTokens())
57  			throw new InvalidNameException("No more tokens expected in name '" +
58  					name + "' (unexpected '" + tokenizer.nextToken() + "')");
59  	}
60  
61  	void assertPrefixEquals(String nameType, String name, String expectedPrefix, String prefix) {
62  		if (!prefix.equals(expectedPrefix)) {
63  			throw new InvalidNameException("Expected " + nameType + " to be prefixed with '" +
64  					expectedPrefix + "' but was '" + prefix + "' for name '" + name + "'");
65  		}
66  	}
67  
68  	public void validateVendorName(String vendorName) {
69  		assertNameContainsValidChars("vendorName", vendorName, vendorName);
70  	}
71  
72  	public void validatePackageFamilyName(String vendorName, String packageFamilyName) {
73  		validateVendorName(vendorName);
74  		StringTokenizer tokenizer = new StringTokenizer(packageFamilyName, ":");
75  		assertPrefixEquals("packageFamilyName", packageFamilyName, vendorName, tokenizer.nextToken());
76  		assertNameContainsValidChars("packageFamilyName", packageFamilyName, tokenizer.nextToken());
77  		assertNoMoreTokens(tokenizer, packageFamilyName);
78  	}
79  
80  	public void validatePackageName(String vendorName, String packageName) {
81  		validateVendorName(vendorName);
82  		StringTokenizer tokenizer = new StringTokenizer(packageName, ":");
83  		assertPrefixEquals("packageName", packageName, vendorName, tokenizer.nextToken());
84  		assertNameContainsValidChars("packageName", packageName, tokenizer.nextToken());
85  		assertNotEmpty("packageName#Version", tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null);
86  	}
87  
88  	private NameValidator() {
89  	}
90  }