1 16 17 package org.springframework.util.xml; 18 19 import java.io.BufferedReader ; 20 import java.io.CharConversionException ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.InputStreamReader ; 24 25 import org.springframework.util.StringUtils; 26 27 34 public class XmlValidationModeDetector { 35 36 40 public static final int VALIDATION_AUTO = 1; 41 42 45 public static final int VALIDATION_DTD = 2; 46 47 50 public static final int VALIDATION_XSD = 3; 51 52 53 57 private static final String DOCTYPE = "DOCTYPE"; 58 59 62 private static final String START_COMMENT = "<!--"; 63 64 67 private static final String END_COMMENT = "-->"; 68 69 70 73 private boolean inComment; 74 75 76 84 public int detectValidationMode(InputStream inputStream) throws IOException { 85 BufferedReader reader = new BufferedReader (new InputStreamReader (inputStream)); 87 try { 88 boolean isDtdValidated = false; 89 String content; 90 while ((content = reader.readLine()) != null) { 91 content = consumeCommentTokens(content); 92 if (this.inComment || !StringUtils.hasText(content)) { 93 continue; 94 } 95 if (hasDoctype(content)) { 96 isDtdValidated = true; 97 break; 98 } 99 if (hasOpeningTag(content)) { 100 break; 102 } 103 } 104 return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD); 105 } 106 catch (CharConversionException ex) { 107 return VALIDATION_AUTO; 110 } 111 finally { 112 reader.close(); 113 } 114 } 115 116 117 120 private boolean hasDoctype(String content) { 121 return (content.indexOf(DOCTYPE) > -1); 122 } 123 124 129 private boolean hasOpeningTag(String content) { 130 if (this.inComment) { 131 return false; 132 } 133 int openTagIndex = content.indexOf('<'); 134 return (openTagIndex > -1 && content.length() > openTagIndex && Character.isLetter(content.charAt(openTagIndex + 1))); 135 } 136 137 143 private String consumeCommentTokens(String line) { 144 if (line.indexOf(START_COMMENT) == -1 && line.indexOf(END_COMMENT) == -1) { 145 return line; 146 } 147 while ((line = consume(line)) != null) { 148 if (!this.inComment && !line.trim().startsWith(START_COMMENT)) { 149 return line; 150 } 151 } 152 return line; 153 } 154 155 159 private String consume(String line) { 160 int index = (this.inComment ? endComment(line) : startComment(line)); 161 return (index == -1 ? null : line.substring(index)); 162 } 163 164 168 private int startComment(String line) { 169 return commentToken(line, START_COMMENT, true); 170 } 171 172 private int endComment(String line) { 173 return commentToken(line, END_COMMENT, false); 174 } 175 176 181 private int commentToken(String line, String token, boolean inCommentIfPresent) { 182 int index = line.indexOf(token); 183 if (index > - 1) { 184 this.inComment = inCommentIfPresent; 185 } 186 return (index == -1 ? index : index + token.length()); 187 } 188 189 } 190 | Popular Tags |