1 16 17 package org.springframework.web.util; 18 19 import java.io.BufferedReader ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.io.InputStreamReader ; 23 import java.io.StreamTokenizer ; 24 import java.util.HashMap ; 25 import java.util.Map ; 26 27 import junit.framework.TestCase; 28 29 33 public class HtmlCharacterEntityReferencesTests extends TestCase { 34 35 private static final String DTD_FILE = "HtmlCharacterEntityReferences.dtd"; 36 37 public void testSupportsAllCharacterEntityReferencesDefinedByHtml() { 38 HtmlCharacterEntityReferences entityReferences = new HtmlCharacterEntityReferences(); 39 Map referenceCharactersMap = getReferenceCharacterMap(); 40 41 for (int character = 0; character < 64000; character++) { 42 if (referenceCharactersMap.containsKey(new Integer (character))) { 43 String referenceName = (String ) referenceCharactersMap.get(new Integer (character)); 44 String fullReference = 45 HtmlCharacterEntityReferences.REFERENCE_START + 46 referenceName + 47 HtmlCharacterEntityReferences.REFERENCE_END; 48 assertTrue("The unicode character " + character + " should be mapped to a reference", 49 entityReferences.isMappedToReference((char) character)); 50 assertEquals("The reference of unicode character " + character + " should be entity " + referenceName, 51 fullReference, entityReferences.convertToReference((char) character)); 52 assertEquals("The entity reference [" + referenceName + "] should be mapped to unicode character " + character, 53 (char) character, entityReferences.convertToCharacter(referenceName)); 54 } 55 else { 56 assertFalse("The unicode character " + character + " should not be mapped to a reference", 57 entityReferences.isMappedToReference((char) character)); 58 assertNull("No entity reference of unicode character " + character + " should exist", 59 entityReferences.convertToReference((char) character)); 60 } 61 } 62 63 assertEquals("The registered entity count of entityReferences should match the number of entity references", 64 referenceCharactersMap.size(), entityReferences.getSupportedReferenceCount()); 65 assertEquals("The HTML 4.0 Standard defines 252 entity references so do entityReferences", 66 252, entityReferences.getSupportedReferenceCount()); 67 68 assertEquals("Invalid entity reference names should not be convertable", 69 (char) -1, entityReferences.convertToCharacter("invalid")); 70 } 71 72 private Map getReferenceCharacterMap() { 73 CharacterEntityResourceIterator entityIterator = new CharacterEntityResourceIterator(); 74 Map referencedCharactersMap = new HashMap (); 75 while (entityIterator.hasNext()) { 76 int character = entityIterator.getReferredCharacter(); 77 String entityName = entityIterator.nextEntry(); 78 referencedCharactersMap.put(new Integer (character), entityName); 79 } 80 return referencedCharactersMap; 81 } 82 83 84 private static class CharacterEntityResourceIterator { 85 86 private final StreamTokenizer tokenizer; 87 88 private String currentEntityName = null; 89 90 private int referredCharacter = -1; 91 92 public CharacterEntityResourceIterator() { 93 try { 94 InputStream inputStream = getClass().getResourceAsStream(DTD_FILE); 95 if (inputStream == null) { 96 throw new IOException ("Cannot find definition resource [" + DTD_FILE + "]"); 97 } 98 tokenizer = new StreamTokenizer (new BufferedReader (new InputStreamReader (inputStream, "UTF-8"))); 99 } 100 catch (IOException ex) { 101 throw new IllegalStateException ("Failed to open definition resource [" + DTD_FILE + "]"); 102 } 103 } 104 105 public boolean hasNext() { 106 return (currentEntityName != null ? true : readNextEntity()); 107 } 108 109 public String nextEntry() { 110 if (hasNext()) { 111 String entityName = currentEntityName; 112 currentEntityName = null; 113 return entityName; 114 } 115 return null; 116 } 117 118 public int getReferredCharacter() { 119 return referredCharacter; 120 } 121 122 private boolean readNextEntity() { 123 try { 124 while (navigateToNextEntity()) { 125 String entityName = nextWordToken(); 126 if ("CDATA".equals(nextWordToken())) { 127 int referredCharacter = nextReferredCharacterId(); 128 if (entityName != null && referredCharacter != -1) { 129 this.currentEntityName = entityName; 130 this.referredCharacter = referredCharacter; 131 return true; 132 } 133 } 134 } 135 return false; 136 } 137 catch (IOException ex) { 138 throw new IllegalStateException ("Could not parse defintion resource: " + ex.getMessage()); 139 } 140 } 141 142 private boolean navigateToNextEntity() throws IOException { 143 while (tokenizer.nextToken() != StreamTokenizer.TT_WORD || !"ENTITY".equals(tokenizer.sval)) { 144 if (tokenizer.ttype == StreamTokenizer.TT_EOF) { 145 return false; 146 } 147 } 148 return true; 149 } 150 151 private int nextReferredCharacterId() throws IOException { 152 String reference = nextWordToken(); 153 if (reference != null && reference.startsWith("&#") && reference.endsWith(";")) { 154 return Integer.parseInt(reference.substring(2, reference.length() - 1)); 155 } 156 return -1; 157 } 158 159 private String nextWordToken() throws IOException { 160 tokenizer.nextToken(); 161 return tokenizer.sval; 162 } 163 } 164 165 } 166 | Popular Tags |